Location: PHPKode > scripts > Simple PHP Indexer > simple-php-indexer/index.php
<?php
//If you want this script to list all of the files in the directory it is in
//and all of the files from the folders underneath the folder it is in
//set recurse to yes.  Otherwise, if you just want a list of files in this
//folder set recurse to no. Make sure only one option is set. Comment out (add
//// in front of) the one you don't want to use. Default is no.   
$recurse = 'NO';
//$recurse = 'YES';

//Create a variable that referees to this file itself.  That way it can be
//excluded from the directory listing.  
$me = basename($_SERVER['PHP_SELF']);

//Create an excluded files array.  Any filenames in the below array will not be
//shown in the directory listing.  Use the pattern below to hide
// as many files as you like. These are case sensitive.   
//NOTE: You can exclude folders as well.  Just list their names without a
//trailing slash. If you hide a directory all files and folders underneath it
//will be hidden as well.
//LIMITATIONS/EXCLUDING THINGS IN FOLDERS:  Things are excluded on a "filename"
//basis, not a "path/filename" basis.  Meaning to exclude documents/resume.doc
//you add a line like this: $exclude[2] = "resume.doc";. However this means
//that school/english111/papers/resume.doc and /resume.doc would also be
////hidden.  This same thing applies to folders as well.  Also filenames and
//folders will both be blocked if one is blocked (ie: excluding "todo" willl
//block todo/ and todo).Basically this means if you want to do anything
//complicated you need all uniquely named folders and files.  For small sites
//this should not be a problem.
$exclude[0] = "this_is_a_hidden_file";
$exclude[1] = "this_is_a_hidden_folder";
//^Hopefully nobody has files and folders named the above things :)
//Time to work with the _description.txt file. This file will allow you to have
//a description for each file in the directory listing. Here is how to use it:
// 1) create a _description.txt file in the same directory that this file is
// in. 2) chmod it at least 744. 3) type filename|description lines. 4)
// seperate each filename description pair by a new line.  Make sure the
// filenames match the *exact* case of the files on your webhost.  Make sure
// you use unix line breaks. In case you are wondering the "_" in the filename
// is just to make sure I don't stop anybody from listing a description.txt
// file they might have in a directory for some reason. 
// Example: 
// cat.jpg|A picture of my cute kitty.
// me.jpg|You know you want me.   
//NOTE: You can add descriptions to folders as well.  Just add their names to
//the _description.txt file without a trailing slash.
//LIMITATIONS/DESCRIBING THINGS IN FOLDERS:  Things are described on a
//"filename" basis, not a "path/filename" basis.  Meaning to describe the file
//documents/resume.doc you would add a line like this: "resume.doc|my resume"
//to _description.txt .  However this means that
//school/english111/papers/resume.doc and /resume.doc would also have the same
//description.  The same thing applies to folders as well.  Also filenames and
//folders will both be described as the same if one is described (ie:
//describing "todo" will describe todo/ and todo).Basically this means if you
//want to do anything complicated you need all uniquely named folders and
//files.  For small sites this should not be a problem.  

//No "if"  checking to see if file exists or if array is built successfully.
// Because we want all the code below to execute even if the description 
// fails. That way you will always get at least a list of files.  If
// _description.txt is not working right for you, you will not get any
// errors, you will just have to figure out the problem yourself.  




//Read entire file in as an array. 
$des_org_array = file("_description.txt");
//Search each "record/line" in the array and replace anything after "|" with
//nothingness. Create a new array with the results.  So from the array that
//holds "cat.jpg|my cat."  comes a new array array for just the filenames, ie
//cat.jpg.  
$des_file_array = preg_replace ("/\|.*/", "", $des_org_array);
//The regular expression above leaves an extra space after the file names, ie
//"cat.jpg " we need to remove this for matching later.  The function below
//will accomplish this.  Taken from php.net/trim. 
function trim_value(&$value)
{
   $value = trim($value);
}
array_walk($des_file_array, 'trim_value');

//Search each "record/line" in the original array and replace anything before
//"|" with nothingness. Create a new array with the results.  So from the array
//that holds "cat.jpg|my cat."  comes a new array array for just the
//descriptions, ie my cat.
$des_des_array = preg_replace ("/.*\|/", "", $des_org_array);
//Now that we have the descriptions and filenames in their own arrays we need
//to make one array with all the data.  The format will be key ==> value.
//filename ==> description.  

// PHP 4 does not have a native array_combine
//function.  So I lifted the below code from php.net's forum.  Props to Ivo van
//Sandick.  
function array_combine_emulated( $keys, $vals ) {
 $keys = array_values( (array) $keys );
 $vals = array_values( (array) $vals );
 $n = max( count( $keys ), count( $vals ) );
 $r = array();
 for( $i=0; $i<$n; $i++ ) {
  $r[ $keys[ $i ] ] = $vals[ $i ];
 }
 return $r;
}
//Now do the work.  Combine the arrays.  
$combined_array = array_combine_emulated($des_file_array, $des_des_array); 

//We need to create an array for the file list itself.  This is necessary
//because readdir does not allow you to do any sorting and shows all files and
//directories in a seemingly random order. We will populate this array later.
$filelist = array();
//Array work done.

//See if the current directory is readable.  It must be to continue.  
//If it is not readable complain.    
if (is_readable("./")) {

//Before we start printing the file list we need to construct the page!
echo"
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"
    \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
<html>
<head>";
//Get the current directory.  Will use this for "Index of.." in the page
//title as well as other places. 
$dirname = dirname($_SERVER["REQUEST_URI"]);


//External CSS
//Use hard coded CSS by default. Change to YES if you want external CSS, be
//sure to update external_css_file.
$use_external_css = 'NO';
//The external CSS file.  This is the file that contains the CSS
//definitions.  Best to keep it outside of the directory this script is in.
$external_css_file = "../style.css";
if ($use_external_css == 'YES')
{
//If using external CSS setup the 'head' section to use that file and don't
//have any hard coded CSS definitions.
echo"
<link rel=\"stylesheet\" href=\"$external_css_file\" />
<title>Index of $dirname </title>
</head>";
}
//Else.  If you are not using an external CSS file.  Don't let 'head' look for
//one and include the hard coded definitions.
elseif ($use_external_css == 'NO')
{
//CSS Definitions
echo"
<style type=\"text/css\">
body.phpdi {background-color: white;
	    color: black;
            text-align: center}
h2.phpdi {text-align: center;
	  font-weight: bold;
          background-color: white}
table.phpdi {border-width: thin thin thin thin;
             border-spacing: 2px;
             border-color: black black black black;
	     border-style: solid solid solid solid;
             border-collapse: collapse;
	     text-align: left;
             empty-cells: show;
             background-color: white;
             margin-left: auto;
	     margin-right: auto}
table.phpdi thead {}
table.phpdi tbody {}
table.phpdi tr {}
table.phpdi th {border-width: thin thin thin thin;
          padding: 1px 1px 1px 1px;
          border-style: solid solid solid solid;
          border-color: black black black black;
          background-color: white;
          color: black;
          font-size:16px;
          text-align: center;
          -moz-border-radius: 0px 0px 0px 0px}
table.phpdi td.phpdi-file {font-family: sans-serif;
              border-width: thin thin thin thin;
              padding: 1px 1px 1px 1px;
              border-style: solid solid solid solid;
              border-color: black black black black;
              background-color: white;
              color: black;
              font-size:14px;
              width: 100px;
              -moz-border-radius: 0px 0px 0px 0px}
table.phpdi td.phpdi-dir {font-style: italic;
             font-family: sans-serif;
	     border-width: thin thin thin thin;
             padding: 1px 1px 1px 1px;
             border-style: solid solid solid solid;
             border-color: black black black black;
             background-color: white;
             color: black;
             font-size:13px;
             width: 100px;
             -moz-border-radius: 0px 0px 0px 0px}
table.phpdi td.phpdi-des {font-family: monospace;
              border-width: thin thin thin thin;
              padding: 1px 1px 1px 1px;
              border-style: solid solid solid solid;
              border-color: black black black black;
              background-color: white;
              font-weight: bold;
	      color: black;
              font-size:10px;
              width: 300px;
              -moz-border-radius: 0px 0px 0px 0px}
a.phpdi:link { color:#0000EE;
               text-decoration: none}
a.phpdi:visited { color: #551A8B;
                  text-decoration: none}
a.phpdi:active {}
a.phpdi:hover {color: #FF0033}
</style>
<title>Index of $dirname</title>
</head>";

}
//CSS IF / ELSE done.  Time to move past the <head>.
//BEGIN HTML
echo"
<body class=\"phpdi\">
<h2 class=\"phpdi\">Index of $dirname</h2>
<table class=\"phpdi\">
<thead>
<tr>
<th>Filename</th>
<th>Description</th>
</tr>
</thead>
<tbody>";

///////////////////////////////////////////////////
/////////NO RECURSE///////////////////////////////
//////////////////////////////////////////////////
//If recurse is set to no.  Just list files in this directory.  
if ($recurse == 'NO')
{

//Open the current directory. 
if ($handle = opendir('.')) {
//Read in the filenames as the file variable.
while ($file = readdir($handle)) {
//If filename is NOT EQUAL TO the following, add the filenames to the filelist
//array.  The values in this array will later be extracted and printed to on
//the site.  In other words Don't ever list the current directory (.) the up a
//directory link (..) this file itself ($me), or the description text file.
//Additionally if the filename is in the exclude array above do not ever list
//it.  Finally if the file begins with a dot (unix hidden files) don't show
//them.

if ($file != "." && $file != ".." && $file != $me && $file != "_description.txt" && $file != in_array($file, $exclude) && substr($file,0,1) != '.') { 


//Populate the filelist array with all files in this directory that DONT
//match the above terms.  
$filelist[] = $file;
}
}
//Close the directory.
closedir($handle);
}
//Sort the array. 
//This will make your file list appear in alphabetical order.  
asort($filelist);
//Loop through the array. The value in each row should be called $file 
//and the following code should be executed against it.   
foreach ($filelist as $file)
{ 

//If filename is a key in the combined_array (meaning it has a description
//defined in _description.txt) list the file and its associated description.
if (array_key_exists($file, $combined_array)) {
//If $file is a directory add a trailing slash to the printed output.  
if (is_dir($file)) {
echo" <tr> 
<td class=\"phpdi-dir\"><a class=\"phpdi\" href=\"$file\">$file/</a></td> 
<td class=\"phpdi-des\">$combined_array[$file]</td>
</tr>";
}
//If the file is not a directory just print the filename and its description.
else {
echo"
<tr >
<td class=\"phpdi-file\"><a class=\"phpdi\" href=\"$file\">$file</a></td>
<td class=\"phpdi-des\">$combined_array[$file]</td>
</tr>";
}
}
//Else.  If the filename is not a key in the combined_array (meaning it does
//not appear in  _description.txt) print a link to the file and a blank
//description.
else {
//If $file is a directory add a trailing slash to the printed output.  
if (is_dir($file)) {
echo "
<tr>
<td class=\"phpdi-dir\"><a class=\"phpdi\" href=\"$file\">$file/</a></td>
<td class=\"phpdi-des\"></td>
</tr>";
}
//If the file is not a directory just print the filename.
else {
echo "
<tr>
<td class=\"phpdi-file\"><a class=\"phpdi\" href=\"$file\">$file</a></td>
<td class=\"phpdi-des\"></td>
</tr>";
}
}
}

//Time to close out the page.
echo"
</tbody>
</table>
</body>
</html>
";


}


////////////////////////////////////////////////////////////////////
////////////////////RECURSE YES/////////////////////////////////////
///////////////////////////////////////////////////////////////////
//If recurse is set to yes. List files in this directory and all
//sub-directories.

//NOTE:
//If you use recursive mode you may notice that everything is in exact (path
//based) alphbetical order. Meaning files may not be broken up in the exact
//same way an that an Operating system would break them up. This is because the
//recursive directory to array function I use below gets all the files in a
//path into an array in one big call.  Then they are all sorted.  If anybody
//has a code snippet that would call each subdirectory into its own array that
//could be sorted and then later merged into a master array let me know.  I'm
// not smart enough to code such a monster. ;)


elseif ($recurse == 'YES')
{

//The below function will read directory contents into an array.
//Taken from http://www.bigbold.com/snippets/posts/show/155.
//Modified some. This will allow us to read all the contents of
//this directory and all sub-directories into an array.
//Once we have the array we will sort it alphabetically
//and print the filenames on the page.
//The comments below the code snippets in the function
//are how I follow the code.  Since I did
//did not write the original code they may not be entirely
//accurate. Parts that start with MOD: are what I added
//to the code.  
function directoryToArray($directory, $recursive) {
//Start function.  Parse var1 as directory.  Parse var2
//as true or false indicating whether to use recursive
//routine or not.

//MOD: 
//First we need to define some global variables so this function can access
//what we assigned at the top of the file. GLOBALS must be enabled for this to
//work. 
global $me;
global $exclude;
global $combined_array;

        $array_items = array();
//Define array for later use.

        if ($handle = opendir($directory)) {
                while (false !== ($file = readdir($handle))) {
//Open the directory specified in the function.
       
//MOD:
//If filename is NOT EQUAL TO the following, add the filenames to the filelist
//array.  The values in this array will later be extracted and printed to on
//the site.  In other words Don't ever list the current directory (.) the up a
//directory link (..) this file itself ($me), or the description text file.
//Additionally if the filename is in the exclude array above do not ever list
//it.  Finally if the file begins with a dot (unix hidden files) don't show
//them.

if ($file != "." && $file != ".." && $file != $me && $file != "_description.txt" && $file != in_array($file, $exclude) && substr($file,0,1) != '.') {

//For every file in that directory that doesn't match the above terms do....
				if (is_dir($directory. "/" . $file)) {
//If the 'file' in the directory opened is a directory do...
                                        if($recursive) {
//If recursive is set, rerun the function on that directory.
                                                $array_items = array_merge($array_items, directoryToArray($directory. "/" . $file, $recursive));
                                        }
//Add the contents of recursed directory to the array.
                                        $file = $directory . "/" . $file;
                                        $array_items[] = preg_replace("/\/\//si", "/", $file);
//If recurse is not set add the directory to the array, replacing // with /
				} else {
                                        $file = $directory . "/" . $file;
                                        $array_items[] = preg_replace("/\/\//si", "/", $file);
//Else if the "file" in the opened directory is a file (not a dir),
//replace // with / and add it to the array.
                                }
                        }
                }
                closedir($handle);
//Close the directory.
//MOD:
//Sort the array alphabetically. 
        asort($array_items);
        }
 return $array_items;
//Return the array.
}
//End borrowed code.

//Create the array filelist by running the function
//on the current directory with recursing enabled. This
//will give us an array with valid path links to the
//files.  ie: ./pic.jpg and ./pics/babes/theron.jpg. 
//Thes entries will be used in our a href statements.  
$filelist = directoryToArray("./", true);


// Lets count the number of slashes (/s) in the relative path
//to this document.  Since the directory this file is in (in relation to
//itself) should always be "./" this should always equal 1. This will be used
//in the variable $spaces below in order to indent
//file in subdirectories. 
$cwd_slash_count = 1;


//Loop through the array. The value in each row should be called $filepath and
//the following code should be executed against it.
foreach ($filelist as $filepath)
{
//Get the filename from the filepath entries in the array.  
//These will be what is shown on the page as links.  In other words: the array
//$filelist holds path entries to files (ie: ./pics/babes/theron.jpg). The
//basename call below turns the above into "theron.jpg".  So what you will end
//up having is <a href="$filepath">$file</a> or <a
//href="pics/babes/theron.jpg">theron.jpg</a>.	  
$file = basename($filepath);

//Count the number of slashes in the relative path to each file.  
//This will be used in the variable $spaces below in order to indent
//file in subdirectories.
$file_slash_count = substr_count($filepath, '/');

//Subtract the number of slashes in the path to this indexer file (./ 1) from
//the number of slashes in the relative path to the files. Save the result as
//$slash_diff.  This will be used in the variable $spaces below in order to
//indent file in subdirectories.
$slash_diff = $file_slash_count - $cwd_slash_count;

//Make variable spaces.
//Here is what it does.  Takes the number of slashes in the relative path
//to your files and then subtracts the amount of slashes in the relative path
//to this file ($slash_diff). The difference is then multiplied by 2.  And the
//product of that determines how many spaces (html &nbsp; s) will come before
//the file link.  This should work in most cases, because a file in a
// directory below the one this file is in will get two spaces in front
// of it, and so on.  People that use symbolic links might run into
// troubles though!
// Meaning files in subdirectories look indented.
// Your output will end up looking like
//this: path (formatted filename).  ./albumlist.txt (albumlist.txt) ./Pink
//Floyd - The //Wall/tracklist.txt (  tracklist.txt) ./Pink Floyd - The
//Wall/CD1/01.mp3 //(    01.mp3).
$spaces = str_repeat( '&nbsp;', ( $slash_diff * 2) );

//If filename is a key in the combined_array (meaning it has a description
//defined in _description.txt) list the file and its associated description.
if (array_key_exists($file, $combined_array)) {
//If $filepath is a directory add a trailing slash to the printed output.
if (is_dir($filepath)) {
echo" <tr>
<td class=\"phpdi-dir\">$spaces $file/</td>
<td class=\"phpdi-des\">$combined_array[$file]</td>
</tr>";
}
//If the file is not a directory just print the filename and its description.
else {
echo"
<tr >
<td class=\"phpdi-file\"><a class=\"phpdi\" href=\"$filepath\">$spaces $file</a></td>
<td class=\"phpdi-des\">$combined_array[$file]</td>
</tr>";
}
}

//Else.  If the filename is not a key in the combined_array (meaning it does
//not appear in  _description.txt) print a link to the file and a blank
//description.
else {
//If $filepath is a directory add a trailing slash to the printed output.
if (is_dir($filepath)) {
echo "
<tr>
<td class=\"phpdi-dir\">$spaces $file/</td>
<td class=\"phpdi-des\"></td>
</tr>";
}
//If the file is not a directory just print the filename.
else {
echo "
<tr>
<td class=\"phpdi-file\"><a class=\"phpdi\" href=\"$filepath\">$spaces $file</a></td>
<td class=\"phpdi-des\"></td>
</tr>";
}
}
//End foreach
}

//Time to close out the page.
echo"
</tbody>
</table>
</body>
</html>
";
}
}

else {
//If the current directory isn't readable complain.  
echo"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"
     \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"><html><head><title>Directory Listing: ERROR</title></head><body><p>Could not list the contents of the directory for some reason.</p></body></html>";
}
?>
Return current item: Simple PHP Indexer