readdir

(PHP 3, PHP 4, PHP 5)

readdir -- 从目录句柄中读取条目

说明

string readdir ( resource dir_handle )

返回目录中下一个文件的文件名。文件名以在文件系统中的排序返回。

参数

dir_handle

目录句柄的 resource,之前由 opendir() 打开

返回值

成功则返回文件名,失败返回 FALSE

范例

例子 1. 列出目录中的所有文件

请留意下面例子中检查 readdir() 返回值的风格。这里明确地测试返回值是否全等于(值和类型都相同――更多信息参见比较运算符FALSE,否则任何目录项的名称求值为 FALSE 的都会导致循环停止(例如一个目录名为“0”)。

<?php
// 注意在 4.0.0-RC2 之前不存在 !== 运算符

if ($handle = opendir('/path/to/files')) {
    echo
"Directory handle: $handle\n";
    echo
"Files:\n";

    
/* 这是正确地遍历目录方法 */
    
while (false !== ($file = readdir($handle))) {
        echo
"$file\n";
    }

    
/* 这是错误地遍历目录的方法 */
    
while ($file = readdir($handle)) {
        echo
"$file\n";
    }

    
closedir($handle);
}
?>

例子 2. 列出当前目录的所有文件并去掉 ...

<?php
if ($handle = opendir('.')) {
    while (
false !== ($file = readdir($handle))) {
        if (
$file != "." && $file != "..") {
            echo
"$file\n";
        }
    }
    
closedir($handle);
}
?>


add a note add a note User Contributed Notes
Adlez
20-Oct-2006 10:58
Another way to sort files from directories.

<?php
$path
= getcwd();
$dh = opendir($path);
print
"Directories <br>************************* <br>";
  while ((
$dir = readdir($dh)) !== false) {
       if (
$dir != "." && $dir != ".." ){
          
$file = @fopen("$path/$dir", "r");
                 if (!
$file){
                     print
"<a href='$dir'>$dir</a><br>";
                 }
       }
  }
 
closedir($dh);

$path = getcwd();
$dh = opendir($path);
print
"<br>Files <br>************************* <br>";
  while ((
$dir = readdir($dh)) !== false) {
       if (
$dir != "." && $dir != ".." ){
          
$file = @fopen("$path/$dir", "r");
                 if (
$file){
                     print
"<a href='$dir'>$dir</a><br>";
                 }
       }
  }
 
closedir($dh);
?>
suit (at) rebell (dot) at
18-Oct-2006 09:23
better version of the yesterdays script

first it reads all content and divides it into files and directorys (two arrays)
then the arrays will be sorted and an output is given (directorys first, then the files)

<?php
$startdir   
= "downloads/";
$dir        = "$startdir$subdir";

echo
"<table border=\"1\">\n";
echo
"<tr>\n";
echo
"<td><a href=\"directory.php\">UP ..</a></td>";
echo
"<td>$subdir</td>";
echo
"</tr>\n";

$array_dir  = array();
$array_file = array();

if (
is_dir($dir)) {
   if (
$dh = opendir($dir)) {
       while ((
$file = readdir($dh)) !== false)
       {
      
$filename = $file;
      
$filetype = filetype($dir . $file);

       if (
$filename == ".." OR $filename == ".")
       {
       echo
"";
       }
       else
           {
               if (
$filetype == "file")
               {
              
$array_file[] = $filename;
               }
               elseif (
$filetype == "dir")
               {
              
$array_dir[] = $filename;
               }
           }
       }
      
closedir($dh);
   }
}

sort($array_dir);
foreach (
$array_dir as $item) {
  
$subdir_n = "$subdir$item/";
           echo
"<tr>\n";
           echo
"<td>dir</td>\n";
           echo
"<td><a href=\"directory.php?subdir=$subdir_n\">$item</a></td>\n";
           echo
"</tr>\n";
}

sort($array_file);
foreach (
$array_file as $item) {
  
$subdir_n = "$subdir$item/";
           echo
"<tr>\n";
           echo
"<td>file</td>\n";
           echo
"<td>$item</td>\n";
           echo
"</tr>\n";
}
echo
"</table>\n";
?>
11-Oct-2006 03:08
Hi, i created a simple module to sort the contents of  a dir
using sort().  In the first part; it get the content of the directory (not sorted) and in the second part; it sort the contents and write line per line the result
Sorry for my poor english;!

<?
$dir
= getcwd(); // the best option is getcwd()
$dh  = opendir($dir);
while (
false !== ($file = readdir($dh))) {
  if (
is_dir($file) && filesize($file)) {} else {  echo "$file\n";}
}

sort($gi); // can be rsort($gi);

while ($cn < $to){
  echo (
"$gi[$cn]\n");
  
$cn = $cn +1;
}

?>
Cynagen cynagen[(at)]gmail_dot_com
03-Oct-2006 05:41
I have recently created a function I have called filearray, which makes use of opendir(), readdir(), and closedir(), to create and output a recursive array in which all files and folders underneath the target main folder ( / = default) that you can parse how you want, array_search it or whatever you need to do. Search 1 or more directories automatically recursively with this.

function filearray($start="/") {
  $dir=opendir($start);
  while (false !== ($found=readdir($dir))) { $getit[]=$found; }
  foreach($getit as $num => $item) {
   if (is_dir($start.$item) && $item!="." && $item!="..") { $output["{$item}"]=filearray($start.$item."/"); }
   if (is_file($start.$item)) { $output["{$item}"]="FILE"; }
  }
  closedir($dir);
  return $output;
}
phpmanual at generic dot depoll dot de
08-Sep-2006 06:36
Guys.. regarding your epic listImages functions:

function listImages($dirname='.') {
   return glob($dirname .'*.{jpg,png,jpeg,gif}', GLOB_BRACE);
}

Cheers,
Niels
runt
06-Sep-2006 01:46
With the help of a clan member from the clan I'm in, I created the following script to give you a password protected list of files that allows directory traversing.  It will not allow you to view any file not in the path you chose.

<?
define
("def_path", 'your path here');
define("def_pass", 'your password here');

$path = def_path;
$pass = "";

foreach (
$_GET as $k => $v) {
   if (
"path"==$k)
      
$path="$v/";
  
   if (
"pass"==$k)
      
$pass="$v";
}

// make sure they cant get access to other files
if (strpos($path,def_path) != false)
  
$path=def_path;
if (
strpos($path,"..")!=false)
  
$path=def_path;
if (!
is_dir($path))
  
$path=def_path;
if (
rtrim(substr_replace($path, ' ', 2, 1000)) != def_path// change 2 to be what you need to get your entire path for the comparison
  
$path=def_path;

function
read_dir($pass, $dirToRead) {
  
$path4 = opendir($dirToRead);
  
$dirs = array();
  
$files = array();
  
   while (
false !== ($file = readdir($path4))) {
       if(
$file!="." && $file!="..") {
           if(
is_dir($dirToRead.$file))
              
$dirs[]=$dirToRead.$file
           else
              
$files[]=$file;   
       }
   }
  
closedir($path4);
  
  
// get the next level up for the
      
$upDir = substr( $dirToRead, 0, strrpos( $dirToRead, '/') );
   if(
strrpos( $dirToRead, '/') + 1 == strlen("$dirToRead"))
      
$upDir = substr( $upDir, 0, strrpos( $upDir, '/') );
   if(
$upDir==""){$upDir=def_path;}
  
  
   echo
"<pre>";
   echo
ltrim(substr_replace($dirToRead, ' ', 0, 1))."\n";
   echo
"<a href=\"?pass=$pass&path=$upDir\">..</a>\n";
  
   if(
$dirs) {
      
natcasesort($dirs);
       foreach(
$dirs as $dir)
           echo
"<a href=\"?pass=$pass&path=$dir\">" . basename($dir) . "</a>\n";
   }
  
   echo
"\n";
   if (
$dirToRead != def_path) {
       if(
$files) {
          
natcasesort($files);
           foreach (
$files as $file)
               echo
$file."\n";
          
           echo
"\n";
       }
   }
   echo
"</pre>";
}
?>
<html><head><title>HMT Fast Download</title></head>
<body bgcolor="#E5E5E5" text="#000000" link="#006699" vlink="#5493B4">
<?
if($pass==def_pass){
   if (
is_dir($path)) {
      
read_dir($pass, $path);
   }
}else if(
$pass==""){
echo
"<form action=\"\" method=\"get\" name=\"loginfrm\">";
echo
"<input name=\"pass\" type=\"text\" value=\"$pass\">";
echo
"<input name=\"login\" type=\"submit\" value=\"login\">";
echo
"</form>";
}
else{
header('Location:http://hitlersmissingtestie.clanservers.com/forum/');
}
?>

</body>
</html>
rasmus dot neikes at web dot de
03-Sep-2006 05:38
I needed a function to offer me a list of files to select from. I used the codes from Marijan Greguric and Rick as a basis and got the following:

<script type="text/JavaScript">
   function pokazi(dir){
       x=document.getElementById(dir);
       if(x.style.display == "none"){
           x.style.display = "";
       }else{
           x.style.display = "none";
       }
   }
</script>

<?php
  
function ls($dir){
      
$handle = opendir($dir);
       for(;(
false !== ($readdir = readdir($handle)));){
           if(
$readdir != '.' && $readdir != '..'){
              
$path = $dir.'/'.$readdir;
               if(
is_dir($path))    $output[$readdir] = $this->ls($path);
               if(
is_file($path))    $output[] = $readdir;
           }
       }
      
closedir($handle);
       return isset(
$output)?$output:false;
      
//closedir($handle);
  
}

   function
throwtree ($dir, $name, $base='', $id='', $return = '') {
       foreach (
$dir as $key=>$node) {
          
$return .= "<dl style=\"border: none; margin:2px;\">";
           if (
is_array ($node)) {
              
$return .= "<dt><a href=\"#\" onClick=\"pokazi('$base$key');return false;\">$key</a></dt><dd style=\" margin-left:20px; display:none;\" id=\"$base$key\">";
              
$nextID = $base."/".$key;
              
$nextBase = "$base$key";
              
$this->throwtree ($node, $name, $nextBase, $nextID, &$return);
              
$return .= "</dd>";
           } else {
              
$return .= "\n<dt><input name=\"$name\" type=\"radio\" value=\"$id/$node\"> $node</dt>\n";
           }
          
$return .= "</dl>";
       }
       return
$return;
   }
?>

They are currently in a class, so you might have to edit the $this-> in the recursions.

The first function ls still creates an array as in the original; the throwtree function uses that array and creates nested defintion-lists of the file- and directory-tree. Nodes can still be folded using JavaScript from Marijan.

The function takes an additional parameter $name from which it generates a list of radio buttons; one per file listed. The values are the paths and file names of the files.

The HTML-String validates; as of now, the JavaScript doesn't degrate gracefully, though. I didn't bother to sort to the array before parsing it, either.

I haven't tested it much yet, but so far it looks good.

Use like this:

<?php

$myclass
->throwtree ($myclass->ls ('path/to/files'), 'radioValue');

?>
ugo.quaisse at gmail.com
12-Jul-2006 10:48
Upgrade of davistummer's code :

You can now list your folder by date
you need to rename your file with this syntax :

"name_-_YYYY-mm-dd.ext"

<?php
function trierdossier($dirname, $sortby, $sortdir) {

$ext = array("jpg", "png", "jpeg", "gif", "pdf", "doc", "txt", "xls");
$files = array();
   if(
$handle = opendir($dirname)) {
       while(
false !== ($file = readdir($handle))){
           for(
$i=0;$i<sizeof($ext);$i++){
               if(
stristr($file, ".".$ext[$i])){ //NOT case sensitive: OK with JpeG, JPG, ecc.
                  
$filesize = filesize($dirname . "/" . $file);
                  
$date3 = explode("_-_",$file);
                  
$date2 = explode(".pdf",$date3[1]);
                  
$date1 = $date2[0];
                  
$date0 = tostamp($date1);
                  
                   if(
$filesize){
                      
$files[] = array(
                                      
"name" => $file,
                                      
"size" => $filesize,
                                      
"date" => $date0
                                
);
                   }
               }
           }
       }
  
closedir($handle);
   }
 
  
//obtain an array of columns
  
foreach ($files as $key => $row) {
      
$name[$key]  = $row['name'];
      
$size[$key] = $row['size'];
      
$date[$key] = $row['date'];
   }
 
return
array_multisort($$sortby, $sortdir, $files) ? $files : false;
}
//end
?>

<?php
//affichage
$sortby = "date"; // sort-by column; accepted values: name OR width OR height OR size
$path = "../upload/argumentaires/lcp/"; // path to folder
$sortdir = SORT_DESC; // sorting order flags; accepted values: SORT_ASC or SORT_DESC
$files = trierdossier($path, $sortby, $sortdir);
foreach (
$files as $file){

echo
$file['name'];
echo
$file['date'];
echo
$file['size'];

}
?>
repley at freemail dot it
23-May-2006 10:27
Upgrade of davidstummer's listImages function: now with order by and sorting direction (like SQL ORDER BY clause).

<?php
//listImages(string path, string sort-by name | width | height | size, int sorting order flags SORT_ASC | SORT_DESC)
function listImages($dirname, $sortby, $sortdir) {

$ext = array("jpg", "png", "jpeg", "gif");
$files = array();
   if(
$handle = opendir($dirname)) {
       while(
false !== ($file = readdir($handle))){
           for(
$i=0;$i<sizeof($ext);$i++){
               if(
stristr($file, ".".$ext[$i])){ //NOT case sensitive: OK with JpeG, JPG, ecc.
                  
$imgdata = getimagesize($dirname . "/" . $file);
                  
$filesize = filesize($dirname . "/" . $file);
                  
//Some formats may contain no image or may contain multiple images.
                   //In these cases, getimagesize() might not be able to properly determine the image size.
                   //getimagesize() will return zero for width and height in these cases.
                  
if($imgdata[0] && $imgdata[1] && $filesize){
                      
$files[] = array(
                                      
"name" => $file,
                                      
"width" => $imgdata[0],
                                      
"height" => $imgdata[1],
                                      
"size" => $filesize
                                
);
                   }
               }
           }
       }
  
closedir($handle);
   }
 
  
//obtain an array of columns
  
foreach ($files as $key => $row) {
      
$name[$key]  = $row['name'];
      
$width[$key] = $row['width'];
      
$height[$key] = $row['height'];
      
$size[$key] = $row['size'];
   }
 
return
array_multisort($$sortby, $sortdir, $files) ? $files : false;
}
//end listImages

//start test
$sortby = "width"; // sort-by column; accepted values: name OR width OR height OR size
$path = "path"; // path to folder
$sortdir = SORT_ASC; // sorting order flags; accepted values: SORT_ASC or SORT_DESC

$files = listImages($path, $sortby, $sortdir);
foreach (
$files as $file){
   echo
'name = <strong>' . $file['name'] . '</strong> width = <strong>' . $file['width'] . '</strong> height = <strong>' . $file['height'] . '</strong> size = <strong>' . $file['size'] . '</strong><br />';
}
//end test
?>

Repley.
repley at freemail dot it
19-May-2006 07:53
BugFix of davidstummer at yahoo dot co dot uk listImages() function:

<?php
function listImages($dirname=".") {
  
$ext = array("jpg", "png", "jpeg", "gif");
  
$files = array();
   if(
$handle = opendir($dirname)) {
       while(
false !== ($file = readdir($handle)))
           for(
$i=0;$i<sizeof($ext);$i++)
               if(
stristr($file, ".".$ext[$i])) //NOT case sensitive: OK with JpeG, JPG, ecc.
                  
$files[] = $file;
      
closedir($handle);
   }
   return(
$files);
}
?>
Thanks to all.

Repley
vorozhko at gmail dot com
19-Apr-2006 04:39
Here is my recursive read dir function, what read dir by mask.
[php]
function ls($dir, $mask /*.php$|.txt$*/)
{
       static $i = 0;
       $files = Array();
       $d = opendir($dir);
       while ($file = readdir($d))
       {
               if ($file == '.' || $file == '..' || eregi($mask, $file) ) continue;
               if (is_dir($dir.'/'.$file))
               {
                       $files += ls($dir.'/'.$file, $mask);
                       continue;
               }
               $files[$i++] = $dir.'/'.$file;
       }
       return $files;
}
$f = ls('E:/www/mymoney/lsdu', ".php$" /*no spaces*/);
[/php]
phathead17 at yahoo dot com
10-Apr-2006 02:14
moogman,

While using your excellent readdirsort function, php complains that the next element in the $items array could not be found.

Instead of:
   if ($items[$last_read_item] == false)

Just use:
   if (!isset($items[$last_read_item]) || $items[$last_read_item] == false)
anonimo
29-Mar-2006 08:06
----------------------
To Marijan Greguric
----------------------

In your script there is a little bug with folders with same name but different path :

i think that is correct to use this id

$id="$path$file";

and not

$id="$file";

bye

L
moogman
23-Feb-2006 07:04
Took cart at kolix dot de's wrapper and changed it into a simple readdir wrapper that does the same, but puts directories first and sorts. Hope it's useful :)

function readdirsort($dir) {
       /* Funktastic readdir wrapper. Puts directories first and sorts. */
       static $not_first_run, $last_read_item=0, $items;

       if (!$not_first_run) {
               $not_first_run = true;
               while (false !== ($file = readdir($dir))) {
                       if (is_dir("$file"))
                               $dirs[] = $file;
                       else
                               $files[] = $file;
               }

               natcasesort($dirs);
               natcasesort($files);

               $items = array_merge($dirs, $files);
       }

       if ($items[$last_read_item] == false)
               return false;
       else
               return $items[$last_read_item++];
}
imran at imranaziz dot net
19-Feb-2006 05:02
Based on tips above, I made this function that displays all php files in your whole website, like a tree. It also displays which directory they're in.

     $dir = $_SERVER['DOCUMENT_ROOT'];
     $shell_command = `find $dir -depth -type f -print`;
     $files = explode ("\n", $shell_command);
     foreach ($files as $value)
     {
         $fileInfo = pathinfo($value);
         $extension = $fileInfo["extension"];
         if ($extension == "php")
         {
           $cur_dir = str_replace($_SERVER['DOCUMENT_ROOT'], "", dirname($value));
           if ($cur_dir != $old_dir)
           {
               echo "<p><b>" . $cur_dir . "</b></p>";
               $old_dir = $cur_dir;
           }
           echo $cur_dir . "/" . basename($value) . "<BR>";
         }
     }

You can change it to take input of certain directory or files of certain, or no extension.
cart at kolix dot de
01-Feb-2006 03:53
*updated version

Here is my recursive read_dir function. It sorts directories and files alphabetically.

<?php
function read_dir($dir) {
  
$path = opendir($dir);
   while (
false !== ($file = readdir($path))) {
       if(
$file!="." && $file!="..") {
           if(
is_file($dir."/".$file))
              
$files[]=$file;
           else
              
$dirs[]=$dir."/".$file;           
       }
   }
   if(
$dirs) {
      
natcasesort($dirs);
       foreach(
$dirs as $dir) {
           echo
$dir;
          
read_dir($dir);
       }
   }
   if(
$files) {
      
natcasesort($files);
       foreach (
$files as $file)
           echo
$file
  
}
  
closedir($path);
}
?>

Start with:
<?php
$path
="path/to/your/dir";
read_dir($path);
?>
Marijan Greguric
31-Jan-2006 01:38
Example directory tree with javascript
<script>
function pokazi(dir){
         alert(dir);
         x=document.getElementById(dir);
         if(x.style.display == "none"){
               x.style.display = "";
         }else{
               x.style.display = "none";
                 }

}
</script>
</head>

<body>

<?php
$path
= "../../upload/";
if (
$handle = opendir($path)) {
   while (
false !== ($file = readdir($handle))) {
       if (
$file != "." && $file != "..") {
           if(
is_dir("$path".$file)){
                 echo
"<div style=\"padding-left: 2px; margin: 0px; border: 1px solid #000000;\"  >";
                 echo
"|-<b><a href=\"#\" onClick=pokazi(\"$file\")>$file</a></b><br />\n";
                
$id="$file";

                
dirT("$path$file/",$id);

           }else{
                 echo
"$file<br />\n";
                 }
       }

   }
   echo
"</div>";
  
closedir($handle);
}
function
dirT($path,$id){
   echo
"<div style=\"padding-left: 2px; margin: 2px; border: 1px solid #000000; display:none \" id=\"$id\">";
           if (
$handle = opendir($path)) {
               while (
false !== ($file = readdir($handle))) {
                       if (
$file != "." && $file != "..") {
                           if(
is_dir("$path".$file)){
                             echo
"<div style=\"padding-left: 10px; margin: 2px; border: 1px solid #000000; \" >";
                             echo
"|-<a href=\"#\" onClick=pokazi(\"$file\")>$file</a><br />\n";
                            
$id="$file";
                            
dirT("$path$file/",$id);
                           }else{
                             echo
"&nbsp;--$file<br />\n";
                           }
               }
           }
           echo
"</div>";
          
closedir($handle);
   }
   echo
"</div>";
}

?>
larry11 at onegentleman dot biz
21-Jan-2006 02:23
After hours of work I found an error in the sort routine sumitted. The correction lies in the fact you need $path.$file to diffirentiate from [dir] or [file] in the routines

$path = "music/Holly Dunn/";
   $dh = opendir($path);

   while (false !== ($file=readdir($dh)))
   {
     if (substr($file,0,1)!=".")
     {
         if (is_dir($path.$file))
        
         $dirs[]=$file.'/'; 
         else
           $files[]=$file; 
     }
   }
   @closedir($dh);

   if ($files)
     natcasesort($files);
   if ($dirs)
     natcasesort($dirs);

   $files=array_merge($dirs,$files);

   foreach ($files as $file)
     echo "<a href=$file>$file</a><br />";

   ?>
info [AT] thijsbaars [DOT] NL
29-Dec-2005 03:39
wrote this piece. I use it to validate my $_GET variables.

It firsts gets the variable $page, cheks if that variable is assinged (on the main index, it is not).
if it is assinged, it checks if it equals one of the found directory's, and then i assigns the variable definatly.

this is a rather secure way of validating the $_GET variable, which on my site should only have the name of one of my directory's.
 
<?php
$page
= $_GET['a'];

if (
$page != "" || !empty($page))
{
  
$handle=opendir('albums');

   while (
false!==($file = readdir($handle)))
   {
       if (
substr($file,0,1)!=".")            //do not look up files or directory's which start with a dot
      
{
           if(!
eregi("thumb",$file))        // all files and dir's containign the word thumb are filtred out
          
{
              
$path = "albums/" . $file;   
               if(
is_dir($path))            // only directory's will get listed
              
{
                   if(
$page != $file) die("wrong argument! only a existing album may be set"); // validates input
                      
else
                       {
                      
$page = "albums/" . $page;
                      
$thumb = $page . thumb;
                       }
               }
           }
       }
   }
  
closedir($handle);
}
doom at inet dot ua
16-Dec-2005 07:10
How i make my directory tree for print (you can make array)

<?php

$First_Dir
= "./my_big_dir";

read_dir($First_Dir);

/**** functions part ****/

function read_dir($name_subdir)
{
$dh = opendir($name_subdir);
while(
gettype($file = readdir($dh))!=boolean)
   {
   if (
$file != '..')
   if (
$file != '.')
         {
        
$current_element = $name_subdir."/".$file;
         if(
is_dir($current_element))
             {
             echo
$current_element."<br>";
            
read_dir($current_element);
             }
         }
   }
closedir($dh);
}
?>

Best free :-)
Absynthe
30-Nov-2005 02:18
This is a function to read all the directories and subdirectories of a folder. It returns an array with all the paths.

<?PHP

$root
= "root";

function
arborescence($root)
{
  
  
$folders  = array();
  
$path    = "$root";
  
$i    = 0;

  
// Vrification de l'ouverture du dossier
  
if ($handle = opendir("./".$path))
   {
      
// Lecture du dossier
      
while ( false !== ($file = readdir($handle)) )
       {
           if (
filetype($path."/".$file) == 'dir')
           {
               if (
$file != '..' && $file != '.' && $file != '' && (substr($file,0,1) != '.'))
               {
                  
$folders[$i] = "./".$path."/".$file;
                  
$i++;
               }
           }
       }
      
closedir($handle);
      
      
// Recherche de tous les sous dossiers pour chaque dossiers
      
for ( $u = 0; $u < $i; $u++ )
       {
           if (
$handle = opendir($folders[$u]))
           {
              
// Lecture du dossier
              
while ( false !== ($file = readdir($handle)) )
               {
                   if (
filetype("./".$folders[$u]."/".$file) == 'dir')
                   {
                       if (
$file != '..' && $file != '.' && $file != '' && (substr($file,0,1) != '.'))
                       {
                          
$folders[$i] = $folders[$u]."/".$file;
                          
$i++;
                       }
                   }
               }
              
closedir($handle);
           }
       }
   }
return
$folders;
}

?>
Martin dot Grossberger at andtek dot com
25-Nov-2005 10:39
to ES:
i believe you are mistaken. readdir() returns a string (the filename), not an array

therefor, the open_dir function should be like this:

function open_dir($dir) {
  $this->dir = $dir;
  $handle = opendir($this->dir);
  if($handle) {
   while(false !== ($file = readdir($handle)) {
     if($file != "." && $file != "..") {
       $files[] = $file;
     }
   }
   sort($files);
   foreach($files as $file) {
     echo $file."<br>";
   }
  }
}
ES
25-Nov-2005 07:58
A simple class to read a dir, and display the files. And will automatically sort the files Alphabetically. Very simple indeed. But thought I'd share (one of my first classes aswell) :)

<?php

class list_dir
{
  var
$dir;

  function
open_dir($dir)
  {
  
$handle = opendir($this->dir);
   if(
$handle)
   {
     while(
false !== ($files = readdir($this->dir)))
     {
       if(
$files != "." && $files != "..")
       {
        
sort($files);
         foreach(
$files as $file)
         {
           echo
$file."<br>";
         }
       }
     }
   }
  }
  function
close_dir()
  {
  
closedir($this->dir);
  }
}
?>

Usage:
<?php

$list
= new list_dir;
$list->open_dir("/path/to/directory/");
$list->close_dir();

?>
24-Sep-2005 05:31
To beanz at gangstersonline dot co dot uk, just a little optimization tip.

You have make a lot of eregi calls in a sequence of elseif statements.  That means that for a worst case, you'll be making 8 eregi calls per iteration.  Instead of using a bunch of conditional eregi() calls (which is much slower compared to preg_match or strpos), you could do the following:

<?php
if ($i)
//create a mapping array
$ext_map = array('exe' => 'exe', 'bmp' => 'image1', etc....)
foreach(
$tab as $rep) {
 
//use one preg_match to grab the extention
 
if (preg_match('/\.([a-z]+)$/', $rep, $matches) {
    
$ext = $ext_map[$matches[1]];
  } else {
    
$ext = 'text';
  }
 
//rest of code...
}
?>

So instead of a worst case of n eregi calls per iteration, you're guaranteed only one preg_match per call.  Or possibly even faster than preg_match:

$ext = $ext_map[substr($rep, strrpos($rep, '.'))];
beanz at gangstersonline dot co dot uk
19-Sep-2005 11:43
A little script I made for my home page on local host. It displays the contents of the folder in which the script is placed, and adds some images in a folder supplied (which is elminated from the file list)

<?PHP
  $list_ignore
= array ('.','..','images','Thumbs.db','index.php'); // Windows server, so thumbs.db shows up :P
 
$handle=opendir(".");
 
$dirs=array();
 
$files=array();
 
$i = 0;
  while (
false !== ($file = readdir($handle))) {
   if (!
in_array($file,$list_ignore)) {
     if(!
eregi("([.]bak)",$file)) { // ignore backup files
      
if(is_dir($file)) {
        
$dirs[]=$file;
       } else {
        
$files[]=$file;
       }
      
$i++;
     }
   }
  }
 
closedir($handle);
 
$tab=array_merge($dirs,$files);
  if (
$i) {
   foreach (
$tab as $rep) {
     if(
eregi("[.]exe", $rep)) {
      
$ext="exe";
     } elseif(
eregi("[.]php", $rep)) {
      
$ext="php";
     } elseif(
eregi("[.]bmp", $rep)) {
      
$ext="image2";
     } elseif(
eregi("[.]doc", $rep)) {
      
$ext="word";
     } elseif(
eregi("[.]xls", $rep)) {
      
$ext="excel";
     } elseif(
eregi("([.]zip)|([.]rar)", $rep)) {
      
$ext="archive";
     } elseif(
eregi("([.]gif)|([.]jpg)|([.]jpeg)|([.]png)", $rep)) {
      
$ext="image";
     } elseif(
eregi("([.]html)|([.]htm)", $rep)) {
      
$ext="firefox";
     } elseif(
$rep[folder]==true) {
      
$ext="folder";
     } else {
      
$ext="text";
     }
     echo (
'<a href="'.$rep.'"><img src="images/'.$ext.'.bmp" border="0"> '.$rep.'</a><br>');
   }
  } else {
   echo
"No files";
  }
?>
anonymous at anonymous dot org
09-Aug-2005 09:11
My simple function for clean up .svn directory
It doesn't recursive, but exec rmdir :P

function clean_svn( $stack )
{
  $dir_list = array();
  $rm_list = array();

  // translate to real path
  $stack = realpath( $stack );

  // Initial dir_list with $stack
  array_push( $dir_list, $stack );

  while( $current_dir = array_pop( $dir_list ) )
  {
   $search = $current_dir . "\\" . "{*,.svn}";

   foreach( glob( $search, GLOB_ONLYDIR | GLOB_BRACE ) as $name )
   {
     if( ereg( '\.svn$', $name ) )
       array_push( $rm_list, $name );
     else
       array_push( $dir_list, $name );
   }
  }

  // remove directory
  foreach( $rm_list as $name )
  {
   exec( "rmdir /S /Q $name" );
  }
}
Basis - basis.klown-network.com
04-Aug-2005 04:11
Alex's example was really good except for just one small part that was keeping it from displaying directories above files in alphabetical order (His has makes the directories and files mixed)

I changed 'if (is_dir($path.$file))' to 'if (is_dir($file))' and it works perfectly now.  Here's the whole block.

<code>
$path = $_SERVER[DOCUMENT_ROOT];
   $dh = @opendir($path);

   while (false !== ($file=@readdir($dh)))
   {
     if (substr($file,0,1)!=".")
     {
         if (is_dir($file))
           $dirs[]=$file.'/'; 
         else
           $files[]=$file; 
     }
   }
   @closedir($dh);

   if ($files)
     natcasesort($files);
   if ($dirs)
     natcasesort($dirs);

   $files=array_merge($dirs,$files);

   foreach ($files as $file)
     echo "<a href=$file>$file</a><br />";
</code>
Alex M
28-Jun-2005 11:37
A shorter and simpler version of twista no[at]$pam rocards $pam[dot]no de
code to first display all folders sorted, and THEN all files sorted. Just like windows.

<?php
   $path
= $_SERVER[DOCUMENT_ROOT]."/old/";
  
$dh = @opendir($path);

   while (
false !== ($file=@readdir($dh)))
   {
     if (
substr($file,0,1)!="."#skip anything that starts with a '.'
    
{                            #i.e.:('.', '..', or any hidden file)
        
if (is_dir($path.$file))
          
$dirs[]=$file.'/'#put directories into dirs[] and append a '/' to differentiate
        
else
          
$files[]=$file#everything else goes into files[]
    
}
   }
   @
closedir($dh);

   if (
$files)
    
natcasesort($files); #natural case insensitive sort
  
if ($dirs)
    
natcasesort($dirs);

  
$files=array_merge($dirs,$files);  #merge dirs[] and files[] into files with dirs first

  
foreach ($files as $file#that's all folks, display sorted all folders and files
    
echo "$file<br>\n";
?>
matthew dot panetta at gmail dot com
16-May-2005 07:44
Here is a simple directory walker class that does not use recursion.
<?
class DirWalker {
   function
go ($dir) {
      
$dirList[] = $dir;
       while ( (
$currDir = array_pop($dirList)) !== NULL ) {
          
$dir = opendir($currDir);
           while((
false!==($file=readdir($dir)))) {
               if(
$file =="." || $file == "..") {
                   continue;
               }
              
              
$fullName = $currDir . DIRECTORY_SEPARATOR . $file;
              
               if (
is_dir ( $fullName ) ) {
                  
array_push ( $dirList, $fullName );
                   continue;
               }
              
              
$this->processFile ($file, $currDir);
           }
          
closedir($dir);
       }
   }
  
   function
processFile ( $file, $dir ) {
       print (
"DirWalker::processFile => $file, $dir\n");
   }
}
?>
twista no[at]$pam rocards $pam[dot]no de
12-Apr-2005 05:18
I used nagash's script from below fo myself, and enhanced it.
It will now first display all folders sorted, and THEN all files sorted. Just like windows :-)

There is also a small function for hiding secret files.

Just set $rootdir to 1 in the root dir, and leave it 0 in all subdirs.

<?

$the_file_array
= Array();
$the_folder_array = Array();
$handle = opendir('./');

while (
false !== ($file = readdir($handle))) {
   if (
$file != ".") {
   if (
filetype($file) == "file") { $the_file_array[] = $file; } else if (filetype($file) == "dir") {$the_folder_array[] = $file; }
   }
}

closedir($handle);
sort ($the_file_array);
reset ($the_file_array);
sort ($the_folder_array);
reset ($the_folder_array);

while (list (
$key, $val) = each ($the_folder_array)) {
   if ((
$val != ".") && (!fnmatch("*.php*", $val))) {
       if ((
fnmatch("~*", $val)) || (fnmatch("~some_thing", $val))) {
          
// CASE: An outcommented file. - Syn: "~<filename>" - Exp: "~nottobeseen.txt"
          
echo "** SECRET FILE **<br>";
       }else{
           if (
$val == "..") {
               if (
$rootdir == "1") {
                  
// CASE: Don't show the way upward if this is the root directory.
                   // Root Directory, do nothing.
              
}else{
                  
// CASE: Show the ".." to go back if this is NOT the root directory.
                  
echo '<a href="'.$val.'/">/'.$val.'/</a><br>';
               }
           }else{
              
// CASE: All normal folders. No ".." and no ".".
              
echo '<a href="'.$val.'/">/'.$val.'/</a><br>';
           }
       }
   }
}

while (list (
$key, $val) = each ($the_file_array)) {
   if ((
$val != ".") && (!fnmatch("*.php*", $val))) {
       if ((
fnmatch("*~~*", $val)) || (fnmatch("~cheat_sux^hi", $val))) {
          
// CASE: An outcommented file. - Syn: "~<filename>" - Exp: "~nottobeseen.txt"
          
echo "** SECRET FILE **<br>";
       }else{
               echo
'<a href="'.$val.'">'.$val.'</a><br>';
           }
   }
}

?>
steve at stevedix dot de
15-Feb-2005 05:12
IT IS VITALLY IMPORTANT that when using opendir and then scanning with readdir, that you test opendir to see if it has returned a valid pointer.

The following code does not :
<?php

$dir
= opendir($mydir);
while((
false!==($file=readdir($dir))))
   if(
$file!="." and $file !="..")
      
unlink($mydir.'/'.$file);
closedir($dir);

?>
if $mydir is not a valid directory resource (for example, the directory in question has been deleted), then the code will loop infinitely.  Of course, it'll stop eventually if you have set a max execution time, but in the meantime it will visibly slow the server.
Anton Fors-Hurdn <atombomben at telia dot com>
21-Dec-2004 05:10
My download function:

<?
function download($dir) {

   if (isset(
$_GET['download'])) {

      
header("Content-Type: octet/stream");
      
header("Content-Disposition: attachment; filename=" . basename($_GET['download']));

       echo
file_get_contents($_GET['download']);

   } else {

     if (
$open = opendir($dir)) {
         while (
false !== ($file = readdir($open))) {
               if (
$file != "." && $file != "..") {
                   if (!
is_dir($dir . $file)) {

                         echo
"< <a href=\"?download=" . $dir . $file . "\">" . $file . "</a><br />\n";

                   } else {

                         echo
"> " . $file . "<br />\n";
                         echo
"<div style=\"padding-left: 15px;\">";
                        
download($dir . $file . "/");
                         echo
"</div>";
                   }
               }
           }
                
closedir($open);
     }
   }
}
?>
boorick[at]utl[dot]ru
16-Dec-2004 06:07
Simple script which counts directories and files in the set directory.

$path = '/path/to/dir'
if ($handle = opendir($path)) {
   while (false !== ($file = readdir($handle))) {
       if ($file != "." && $file != "..") {
           $fName = $file;
           $file = $path.'/'.$file;
           if(is_file($file)) $numfile++;
           if(is_dir($file))  $numdir++;
       };
   };
   closedir($handle);
};
echo $numfiles.' files in a directory';
echo $numdir.' subdirectory in directory';
BY626
07-Dec-2004 06:15
here is a simple directory navigating script i created. files and directories are links and it displays the current directory and the path relative to the file the script is in. it also has a nifty 'up one level' link.
------

<?php
   $path
= $_GET['path'];
   if(!isset(
$path))
   {
      
$path = ".";
   }

   if (
$handle = opendir($path))
   {
      
$curDir = substr($path, (strrpos(dirname($path."/."),"/")+1));
       print
"current directory: ".$curDir."<br>************************<br>";   
       print
"Path: ".dirname($path."/.")."<br>************************<br>";

       while (
false !== ($file = readdir($handle)))
       {
           if (
$file != "." && $file != "..")
           {
              
$fName = $file;
              
$file = $path.'/'.$file;
               if(
is_file($file))
               {
                   print
"[F]&nbsp;&nbsp;<a href='".$file."'>".$fName."</a>&nbsp;&nbsp;&nbsp; ".filesize($file)." bytes<br>";
               }
               if(
is_dir($file))

               {
                   print
"[D]&nbsp;&nbsp;<a href='ex2.php?path=$file'>$fName</a><br>";
               }
           }
       }
      
$up = substr($path, 0, (strrpos(dirname($path."/."),"/")));
       print
"[^]&nbsp;&nbsp;<a href='ex2.php?path=$up'>up one level</a><br>";

      
closedir($handle);
   }
?>

------ sample output ------

current directory: kate
************************
Path: ./kate
************************
[F]  xyz_file.txt  13005 bytes
[F]  mno_file.txt  26327 bytes
[F]  abc_file.txt  8640 bytes
[D]  k2
[^]  up one level
Jason Wong
13-Nov-2004 06:20
Everyone seems to be using recursion for trawling through subdirectories. Here's a function that does not use recursion.

<?php
  
function list_directory($dir) {
      
$file_list = '';
      
$stack[] = $dir;
       while (
$stack) {
          
$current_dir = array_pop($stack);
           if (
$dh = opendir($current_dir)) {
               while ((
$file = readdir($dh)) !== false) {
                   if (
$file !== '.' AND $file !== '..') {
                      
$current_file = "{$current_dir}/{$file}";
                       if (
is_file($current_file)) {
                          
$file_list[] = "{$current_dir}/{$file}";
                       } elseif (
is_dir($current_file)) {
                          
$stack[] = $current_file;
                       }
                   }
               }
           }
       }
       return
$file_list;
   }
?>

I also did a rudimentary benchmark against Rick's function (no reason in particular why I chose Rick's, it was just the latest) and the result is that using recursion results in about 50% longer execution time.

Details of benchmark:
Directory contains 64 subdirectories and about 117,000 files. Each function was executed 100 times in a for-loop and the average time per iteration was calculated. The result is 3.77 seconds for the non-recursive function and 5.65 seconds for the recursive function.
Rick at Webfanaat dot nl
29-Sep-2004 06:47
Yet another recursive directory lister :P
Why did I create it?
I like to keep things small, and it seems like all the scripts around here are a lot bigger and more complex while they produce the same (or nearly the same) output.

This one creates a multidimensional array with the folders as associative array and the files as values.
It puts the name of the folders and files in it, not the complete path (I find that annoying but its easy to change that if you prefer it with the path).

And I used a for loop instead of a while loop like everyone around here does.
Why?
1. I just like for loops.
2. Everyone else uses a while loop.

<?php
function ls($dir){
  
$handle = opendir($dir);
   for(;(
false !== ($readdir = readdir($handle)));){
       if(
$readdir != '.' && $readdir != '..'){
          
$path = $dir.'/'.$readdir;
           if(
is_dir($path))    $output[$readdir] = ls($path);
           if(
is_file($path))    $output[] = $readdir;
       }
   }
   return isset(
$output)?$output:false;
  
closedir($handle);
}

print_r(ls('.'));
?>

PS: if you don't need the files in it then you can just comment out the "if(is_file....." part.
nagash at trumna dot pl
06-Jun-2004 01:11
Simplified recursive file listing (in one directory), with links to the files.

<?
$the_array
= Array();
$handle = opendir('prace/.');
while (
false !== ($file = readdir($handle))) {
   if (
$file != "." && $file != "..") {
  
$the_array[] = $file;
   }
}
closedir($handle);
sort ($the_array);
reset ($the_array);
while (list (
$key, $val) = each ($the_array)) {
   echo
"<a href=prace.php?id=$val>$val</a><br>";
}
?>

I'm not sure, if you were talking about that, but anyway I think somebody might find it usefull :-)
phpuser at php dot net
04-Jun-2004 11:28
Simplified recursive directory listing. Returns FolderListing object which contains an array with all the directories and files.

<?php

class FolderListing {
   var
$newarr = array();

   function
loop($stack) {
       if(
count($stack) > 0) {
          
$arr = array();
           foreach(
$stack as $key => $value) {
              
array_push($this->newarr, $stack[$key]);
               if (
$dir = @opendir($stack[$key])) {
                   while ((
$file = readdir($dir)) !== false) {
                       if ((
$file != '.') && ($file != '..')) {
                          
array_push($arr, $stack[$key].'/'.$file);
                       }
                   }
               }
              
closedir($dir);
           }
          
$this->loop($arr);
       } else {
          
$sorted = sort($this->newarr);
           return(
$sorted);
       }
   }
}

$start = new FolderListing;
$base = array("baseDir");
$start->loop($base);

foreach(
$start->newarr as $value) {
   echo
$value."<br />";
}

?>

Add the following code around the array_push line to just check for directories:

if(is_dir($stack[$key].'/'.$file)) {

}
jw5_feedback at comcast dot net
20-May-2004 06:30
Ok you have seen a bunch of them recursive directory functions, but heres mine that loads them all into an array and emdeded arrays that contain all the file names.

/*********************************************/

$main_dir = "downloads";

$A_main = Array($main_dir,);
$start =& $A_main;
$j = 0;

function dir_recurse($dir,&$wia) {
  $i = 1;
  if($handle = opendir($dir)) {
   while(false !== ($file = readdir($handle))) {
   if($file != "." && $file != ".." ) {
     if(is_dir($dir."/".$file) == true) {
     $fullpath = $dir."/".$file;
     array_push($wia,array($file));
     dir_recurse($fullpath,$wia[$i]);
     $i++;
     }
     else {
     $fullpath = $dir."/".$file;
     array_push($wia,$fullpath);
     $i++;
     }
   }
   }
  closedir($handle);
 }
}

dir_recurse($main_dir,$start);

/********************************************/

wia stands for "where it's at" in relation to being in a  directory.
jw5_feedback at comcast dot net
21-May-2004 09:30
Ok you have seen a bunch of them recursive directory functions, but heres mine that loads them all into an array and emdeded arrays that contain all the file names.

/*********************************************/

$main_dir = "downloads";

$A_main = Array($main_dir,);
$start =& $A_main;
$j = 0;

function dir_recurse($dir,&$wia) {
  $i = 1;
  if($handle = opendir($dir)) {
   while(false !== ($file = readdir($handle))) {
   if($file != "." && $file != ".." ) {
     if(is_dir($dir."/".$file) == true) {
     $fullpath = $dir."/".$file;
     array_push($wia,array($file));
     dir_recurse($fullpath,$wia[$i]);
     $i++;
     }
     else {
     $fullpath = $dir."/".$file;
     array_push($wia,$fullpath);
     $i++;
     }
   }
   }
  closedir($handle);
 }
}

dir_recurse($main_dir,$start);

/********************************************/

wia stands for "where it's at" in relation to being in a  directory.
abanner at netachievement dot co dot uk
12-May-2004 08:04
Whilst writing a script to check a directory to see whether certain files existed, I used an original example from this page and modified so that in the first loop that checks the directory, there is a second that looks at a database recordset and tries to find the matches.

I found an issue that I have not yet solved. I am not a PHP guru, so I might be missing something here.

In the parent loop, $file is set correctly. As soon as your progress to the inner loop, $file becomes just a full stop (.) - I've no idea why.

<?

if ($handle = opendir($path)) :
     while (
false !== ($file = readdir($handle))) :
      
// Here $file is set correctly
      
while($row = @ mysql_fetch_array($result)) :
          
// Here $file is set to .

      
endwhile;
   endwhile;
  
  
closedir($handle);
endif;
?>
phpnet at public dot buyagun dot org
06-May-2004 08:10
Another simple recusive directory listing function.

<?php
$BASEDIR
="/tmp";
function
recursedir($BASEDIR) {
      
$hndl=opendir($BASEDIR);
       while(
$file=readdir($hndl)) {
               if (
$file=='.' || $file=='..') continue;
                      
$completepath="$BASEDIR/$file";
                       if (
is_dir($completepath)) {
                              
# its a dir, recurse.
                              
recursedir($BASEDIR.'/'.$file);
                               print
"DIR: $BASEDIR/$file<br>\n";
                       } else {
                              
# its a file.
                              
print "FILE: $BASEDIR/$file<br>\n";
                       }
       }
}
recursedir($BASEDIR);
?>
juanma at teslg dot com
06-Apr-2004 11:13
This is a recursive function using readdir. It creates an Dir tree called Directorio on memory.
   class Directorio
   {
       var $path="";
       var $arrPathFich=array();
      
       function Directorio()
       {
           if(func_num_args()==1)
           {
               $arr=func_get_args();
               $obj=$arr[0];
               $this->path=$obj->path;
               $this->arrPathFich=$obj->arrPathFich;
           }
       }
   }//Directorio

/* *** FUNCIONES *** */
function getArbolDir($dir)
{
   $direct=new Directorio();
   $direct->path=$dir;
   $i=0;
   $dir.='/';
   if(is_dir($dir))
   {
       $pdir=opendir($dir);
       while(FALSE !== ($nomfich=readdir($pdir)))
       {
           if($nomfich!="." && $nomfich!="..")
               if(is_dir($dir.$nomfich))
                   $direct->arrPathFich[$i++]=new Directorio(getArbolDir($dir.$nomfich));
               else
                   $direct->arrPathFich[$i++]=$dir.$nomfich;
       }
       closedir($pdir);
   }
   return $direct;
}//getArbolDir
gehring[at-no-2-spam]egotec.com
18-Mar-2004 10:13
If you want to walk through a directory and want to use a callback function for every dir or file you get you can use this

its like the perl File::Find method "find"

<?php
  
function find($callback, $dir=Array())
   {
       foreach(
$dir as $sPath) {
           if (
$handle = opendir($sPath)) {
               while (
false !== ($file = readdir($handle))) {
                   if(
$file !== "." && $file !== "..") {
                       if(
is_dir($sPath."/".$file)) {
                           eval(
"$callback(\"$sPath\", \"$file\");");
                          
find($callback, Array($sPath."/".$file));
                       } else {
                           eval(
"$callback(\"$sPath\", \"$file\");");
                       }
                   }
               }
              
closedir($handle);
           }
       }
   }

   function
walk($dir, $file)
   {
       print
">>> $dir/$file\n";
   }

  
find("walk", Array("/etc"));
?>

hope it helps
jg
josh at duovibe dot com
13-Mar-2004 07:31
After looking for awhile for a function which retrieves a folder listing based on certain criteria (return folder, files, or both; search recursively or not), I decided to write my own.  Maybe somebody out there will find it helpful.

Currently, it returns a flat list, but that can changed to return a nested list by editing the line:
     $file_list = array_merge($file_list, directory_list($path ...
to
     $file_list[] = directory_list($path ...

function directory_list($path, $types="directories", $recursive=0) {
  
   // get a list of just the dirs and turn the list into an array
   // @path        starting path from which to search
   // @types        can be "directories", "files", or "all"
   // @recursive    determines whether subdirectories are searched
  
   if ($dir = opendir($path)) {
       $file_list = array();
       while (false !== ($file = readdir($dir))){
           // ignore the . and .. file references
           if ($file != '.' && $file != '..') {
               // check whether this is a file or directory and whether we're interested in that type
               if ((is_dir($path."/".$file)) && (($types=="directories") || ($types=="all"))) {
                       $file_list[] = $file;
                       // if we're in a directory and we want recursive behavior, call this function again
                       if ($recursive) {
                           $file_list = array_merge($file_list, directory_list($path."/".$file."/", $types, $recursive));
                       }
               } else if (($types == "files") || ($types == "all")) {
                   $file_list[] = $file;
               }
           }
       }
       closedir($dir);
       return $file_list;
   } else {
       return false;
   }
  
}
Angryman Bluts
24-Feb-2004 01:52
If anyone uses the posted script of mikael[at]limpreacher[d0t]com
...

U should use direcho($path.file.'/');
rockinmusicgv at y_NOSPAM_ahoo dot com
28-Nov-2003 03:24
Mainly an extension of the other drop down directory lists
Except it should handle hidden directories (unix)

function getdirs($directory, $select_name, $selected = "") {
   if ($dir = @opendir($directory)) {
       while (($file = readdir($dir)) !== false) {
           if ($file != ".." && $file != ".") {
   if(is_dir($file)) {
   if(!($file[0] == '.')) {
               $filelist[] = $file;
   }
               }
           }
       }
           closedir($dir);
   }
   echo "<select name=\"$select_name\">";
   asort($filelist);
   while (list ($key, $val) = each ($filelist)) {
       echo "<option value=\"$val\"";
       if ($selected == $val) {
           echo " selected";
       }
       echo ">$val</option>";
   }
   echo "</select>";
}
Steve Main
26-Nov-2003 12:53
This will allow you to print out a total recursive directory listing no files just directories for possible tree menues that need folder lists.

<?php
$DirectoriesToScan 
= array(realpath('/var/www/axim.caspan.com/Software/'));
$DirectoriesScanned = array();

while (
count($DirectoriesToScan) > 0) {
  foreach (
$DirectoriesToScan as $DirectoryKey => $startingdir) {
   if (
$dir = @opendir($startingdir)) {
     while ((
$file = readdir($dir)) !== false) {
       if ((
$file != '.') && ($file != '..')) {
        
$RealPathName = realpath($startingdir.'/'.$file);
         if (
is_dir($RealPathName)) {
           if (!
in_array($RealPathName, $DirectoriesScanned) && !in_array($RealPathName, $DirectoriesToScan)) {
            
$DirectoriesToScan[] = $RealPathName;
          
$DirList[] = $RealPathName;
           }
         }
       }
     }
    
closedir($dir);
   }
  
$DirectoriesScanned[] = $startingdir;
   unset(
$DirectoriesToScan[$DirectoryKey]);
  }
}

$DirList = array_unique($DirList);
sort($DirList);

foreach (
$DirList as $dirname) {
  echo
$dirname."<br>";
}

?>
bermi_ferrer {:at:} bermi {:dot:} org
07-Nov-2003 08:09
Simple function to recursively load given directory (/full_path/to_directory/) into an array.

function akelos_recursive_dir($directorio)
{
   if ($id_dir = opendir($directorio)){
       while (false !== ($archivo = readdir($id_dir))){
           if ($archivo != "." && $archivo != ".."){
               if(is_dir($directorio.$archivo)){
                   $resultado[$archivo] = akelos_recursive_dir($directorio.$archivo."/");
               }
               else{
                   $resultado[] = $archivo;
               }
           }
       }
       closedir($id_dir);
   }
   return $resultado;
}
mikael[at]limpreacher[d0t]com
06-Nov-2003 09:28
I don't know if I haven't had the patience to go trough enough notes, but I didn't find any tip on how to recurively get a directory listing (show subdirectories too), so, as many other, I wrote one. Hopefully this will help someone.

<?php
        
function direcho($path) {
                 if (
$dir = opendir($path)) {
                     while (
false !== ($file = readdir($dir))){
                         if (
is_dir($path.$file)) {                    // if it's a dir, check it's contents too
                            
if ($file != '.' && $file != '..') {      // ...but dont go recursive on '.' and '..'
                                
echo '<li><b>' . $file . '</b></li><ul>';
                                
direcho($path.$file); // This is a feature that surprised me, it IS possible to call
                                                       // the function itself from inside that function.
                                
echo '</ul>';
                             }
                             else { 
//if it IS '.' or '..' , just output.
                                
echo '<li><b>' . $file . '</b></li>';
                             }
                         }
                         else { 
//if it's not a dir, just output.
                            
echo '<li>' . $file . '</li>';
                         }
                     }
                    
closedir($dir);
                 }
         }
direcho('/path/to/home/dir/'); // somehow only the absolute path ('/home/yourhomedir/public_html/testdir/') worked for me...

?>

Yippii! my first contribution to this site!
php at trap-door dot co dot uk
28-Sep-2003 11:22
An extension to the sorted file list in a drop-down box posted by paCkeTroUTer at iprimus dot com dot au.

Takes the directory, the "name" of the form element it produces, and optionally, a filename. If the file name is in the list, it will be the default selection in the list.

<?

function listfiles($directory, $select_name, $selected = "") {
   if (
$dir = @opendir($directory)) {
       while ((
$file = readdir($dir)) !== false) {
           if (
$file != ".." && $file != ".") {
              
$filelist[] = $file;
           }
       }
          
closedir($dir);
   }
   echo
"<select name=\"$select_name\">";
  
asort($filelist);
   while (list (
$key, $val) = each ($filelist)) {
       echo
"<option value=\"$val\"";
       if (
$selected == $val) {
           echo
" selected";
       }
       echo
">$val</option>";
   }
   echo
"</select>";
}

?>

Hope this helps someone.
alfred-baudisch at bol dot com dot br
18-Jul-2003 01:27
I use the function below in my site, is good if you wanna only images files on the filename array.

function GetFileList($dirname, $extensoes = FALSE, $reverso = FALSE)
{
   if(!$extensoes) //EXTENSIONS OF FILE YOU WANNA SEE IN THE ARRAY
       $extensoes = array("jpg", "png", "jpeg", "gif");
  
   $files = array();

   $dir = opendir($dirname);

   while(false !== ($file = readdir($dir)))
   {
       //GET THE FILES ACCORDING TO THE EXTENSIONS ON THE ARRAY
       for ($i = 0; $i < count($extensoes); $i++)
       {
           if (eregi("\.". $extensoes[$i] ."$", $file))
           {
               $files[] = $file;
           }
       }
   }

   //CLOSE THE HANDLE
   closedir($dirname);

   //ORDER OF THE ARRAY
   if ($reverso) {
       rsort($files);
   } else {
       sort($files);
   }

   return $files;
}
web at fischenich dot org
15-Jul-2003 11:11
Why not sorting by filemtime like this?

  $handle=opendir($fPath);
  while ($file = readdir($handle))
   {
     if($file=='.'||$file=='..')
       continue;
     if (preg_match("/\.(esp|xml)$/", $file)){
       $filetlist [$file] = filemtime ($fPath.'/'.$file);
     }
   }
  asort($filetlist);

  while (list ($key, $val) = each ($filetlist))
  {
     echo $key;
   }
thebitman at attbi dot com
30-Apr-2003 06:29
On sorting by date- no, you can't just use an associative array since some things /will/ be created on the same second. No reason why you can't append the filename to the time, though! (used md5() to kill any weird characters in a unique way)

$dirpath = getcwd() . "/";
$dir = opendir($dirpath);
$files = array();
while ($file = readdir($dir)) {
   $localpath = $dirpath.$file;
  
   if (is_file($localpath)) {
       $key = filemtime($localpath).md5($file);
       $files[$key] = $file;
   }
}
ksort($files);
foreach ($files as $file) {
   echo "$file<br>";
}
paCkeTroUTer at iprimus dot com dot au
25-Apr-2003 07:06
This is an example of how to sort directories alphabetically into a drop down list:

           <?
          
if ($dir = @opendir("products"))
           {
               while ((
$file = readdir($dir)) !== false)
               {
                   if(
$file != ".." && $file != ".")
                   {
                      
$filelist[] = $file;
                   }
               }
              
closedir($dir);
           }
          
?>
<form>
           <select name="selected_dir" >
           <?php
           asort
($filelist);
           while (list (
$key, $val) = each ($filelist))
           {
               echo
"<option>$val</option>";
           }
          
?>
            </select>
</form>
06-Mar-2003 11:34
Here is a function that will recursively copy a file into every directory within a specified directory, unless the directory is in an optional third parameter, an array with a list of directory names to skip. It will also print whether it copied each item it expected to.

Also, if you try to copy a file to itself in PHP, you end up with an empty file. To alleviate this, there is a fourth parameter, also optional, which is the number of levels to skip when copying files. The default is 0, which will only skip the directory specified in $dir, so that a call using the file's directory will work properly. I would not recommend calling this function with a directory higher up the tree than $file's.

<?php
function copyintodir ($file, $dir, $skip = array(''), $level_count = 0) {
  if (
count($skip) == 1) {
  
$skip = array("$skip");
  }
  if (!@(
$thisdir = opendir($dir))) {
   print
"could not open $dir<br />";
   return;
  }
  while (
$item = readdir($thisdir) ) {
   if (
is_dir("$dir/$item") && (substr("$item", 0, 1) != '.') && (!in_array($item, $skip))) {
    
copyintodir($file, "$dir/$item", $skip, $level_count + 1);
   }
  }
  if (
$level_count > 0) {
   if (@
copy($file, "$dir/$file")) {
     print
"Copied $file into $dir/$file<br />\n";
   } else {
     print
"Could not copy $file into $dir/$file<br />\n";
   }
  }
}
?>
You can call it using a function call such as this:

copyintodir ('index.php', '.', 'images');
php at silisoftware dot com
31-Jan-2003 02:16
Yet another recursive directory listing script. This one returns a list of all absolute filenames (files only, no directories) in or below the directory first specified in $DirectoriesToScan.

$DirectoriesToScan  = array(realpath('.'));
$DirectoriesScanned = array();
while (count($DirectoriesToScan) > 0) {
  foreach ($DirectoriesToScan as $DirectoryKey => $startingdir) {
   if ($dir = @opendir($startingdir)) {
     while (($file = readdir($dir)) !== false) {
       if (($file != '.') && ($file != '..')) {
         $RealPathName = realpath($startingdir.'/'.$file);
         if (is_dir($RealPathName)) {
           if (!in_array($RealPathName, $DirectoriesScanned) && !in_array($RealPathName, $DirectoriesToScan)) {
             $DirectoriesToScan[] = $RealPathName;
           }
         } elseif (is_file($RealPathName)) {
           $FilesInDir[] = $RealPathName;
         }
       }
     }
     closedir($dir);
   }
   $DirectoriesScanned[] = $startingdir;
   unset($DirectoriesToScan[$DirectoryKey]);
  }
}

$FilesInDir = array_unique($FilesInDir);
sort($FilesInDir);

foreach ($FilesInDir as $filename) {
  echo $filename."\n";
}
nick_vollebergh at hotmail dot com
07-Jan-2003 04:53
This is a good way to put all your files from a directory in an arry, and echo them on your page.

<?php

$the_array
= Array();
$handle = opendir('.');

while (
false !== ($file = readdir($handle))) {
   if (
$file != "." && $file != "..") {  /* as descripted below: these "files" will not be added to the array */
      
$the_array[] = $file;
   }
}
closedir($handle);

foreach (
$the_array as $element) {
  echo
"$element @br /@ \n";
}

?>
php dot net at phor dot net
05-Jan-2003 07:34
This is equivilent to (and more modular than): $file_list=explode("\n",`find $path -type f`)

  function walk_dir($path)
  {
   if ($dir = opendir($path)) {
     while (false !== ($file = readdir($dir)))
     {
       if ($file[0]==".") continue;
       if (is_dir($path."/".$file))
         $retval = array_merge($retval,walk_dir($path."/".$file));
       else if (is_file($path."/".$file))
         $retval[]=$path."/".$file;
     }
     closedir($dir);
   }
   return $retval;
  }

-- Full Decent
rolandfx_SPAMMENOT_ at bellsouth dot net
11-Nov-2002 05:04
While I won't make any claims as to its efficiency, this modified version of me@infinito.dk's script above does do several things the previous one doesn't.  It will display jpegs using the .jpeg extension, and will not show double-extended files (foo.jpg.bar), nor will it show non-image files with an extension in their name, like mygif.html.

<?
function CheckExt($filename, $ext) {
$passed = FALSE;
$testExt = "\.".$ext."$";
if (
eregi($testExt, $filename)) {
$passed = TRUE;
}
return
$passed;
}

//Define an array of common extensions.
$exts = array("gif","jpg$|\\.jpeg","png","bmp");

echo
"<b>Images in this folder:</b>";
$dir = opendir(".");
$files = readdir($dir);

while (
false !== ($files = readdir($dir))) {
foreach (
$exts as $value) {
if (
CheckExt($files, $value)) {
echo
"<a href=\"$files\">$files</a>\n";
$count++; //Keep track of the total number of files.
break; //No need to keep looping if we've got a match.
}
}

}
echo
$count." image(s) found in this directory.\n";
echo
"<a href=\"".$_SERVER["PHP_SELF"]."\">Refresh</a>\n";
//Be a good script and clean up after yourself...
closedir($dir);

?>
Silphy@nowhere
08-Nov-2002 11:26
Mod'ed the code a bit. Made it so the dir is selected by dir.php?dir=name . I made it to parse anything starting with "/" "." or "./" so there shouldn't be any security risks when using this.

<?php

$directory
= $_REQUEST["dir"];    // lets fetch the variable: REQUEST works for both, POST and GET methods

if (substr($directory, 0, 1) == "/")
  
$directory = "";
$directory = str_replace ("./", "", $directory);
$directory = str_replace (".", "", $directory);

if (
$directory != @$null) {    // lets check if the variable "dir" has something in it, otherwise lets just print out the empty document
  
if ($dir = @opendir($directory)) {    // changed "./" to the directory variable
      
echo ("Listing contents of <b>$directory</b><br><br>\n");    // i just added this thing
      
while (($file = readdir($dir)) !== false) {
           if (
$file != "." && $file != "..") {
              
$location = "$directory/$file";
              
$type = filetype($location);
              
$size = filesize($location);
               if (
is_dir($location) == true) {
               echo (
"$type - <a href=\"dir.php?dir=$location\">$file</a><br>\n");
               }
               else {
               echo (
"$type - <a href=\"$location\">$file</a> - $size Bytes<br>\n");
               }
           }
       }
      
closedir($dir);
   }
}

?>
eric.draven[AT]tiscalinet[DOT]it
25-Aug-2002 03:39
Sometimes happens that you need to sort your files by date , but using associative arrays you won't be able to list files that were written in the same second (rarely , but with CMS system it's strangely frequent , doh!). Here's something that may come in hand in such a case. Code CAN really be improved (especially flags), but you can figure out the trick.

$dir = opendir($myDir);
while (($file = readdir($dir)) !== false) {
  if ($file != "." and $file != "..") {
   $fileTime=filemtime($docsPath.$file);
   $stillExists = true;
   while ($stillExists) {
                   $stillExists = validateTs($fileTime);
                   if (!$stillExists) {
                       $articlesToProcess[$fileTime] = $file;
                   }
                   else {
                       echo("<font color=\"red\" size=\"3\">found ts equals to another key. add 1 second and retry </font><br>");
                       $fileTime++;
                   }
               }
              
           }
       }
       krsort($articlesToProcess);

# Follow function that do the work

function validateTs($fileTime) {
       global $articlesToProcess;       
       foreach($articlesToProcess as $key => $value) {
           if ($fileTime == $key) {
               return true;
           }
          
       }
       return false;
   }

email me for comments. 

Marcus
vjtNO at SPAMazzurra dot org
05-Aug-2002 07:09
to skip hidden files ( on unix ), you can do:

$d = opendir('/path/to/dir');
while(($f = readdir($d)) !== false)
{
   if($f[0] == '.')
       continue;
   /* .. your code here .. */
}
mb at michaelborchers dot net
22-Jul-2002 12:16
I tried to find a script that would put all files of one directory($img_path) into an array while excluding any subdirectory, not only ".", ".." or "xyz".
Chriss found the solution some threads above.

The following way the slashes are used work for both- LINUX and WIN:

$handle = opendir("$img_path");
  while (false !== ($file = readdir($handle))) {
   if(is_file($img_path."//".$file)) {
     $filelist[] = $file;
     $anz_files = count($filelist);
   }
  }
phpwizard-at-pech-dot-cz
05-Jul-2002 04:22
It should work, but it'll be better to read section 13.1.3 Cache-control Mechanisms of RFC 2616 available at http://rfc.net/rfc2616.html before you start with confusing proxies on the way from you and the client.

Reading it is the best way to learn how proxies work, what should you do to modify cache-related headers of your documents and what you should never do again. :-)

And of course not reading RFCs is the best way to never learn how internet works and the best way to behave like Microsoft corp.

Have a nice day!
Jirka Pech
rmadriz at expressmail dot net
22-May-2002 07:54
One little note about the is_dir() and is_file() functions when used with readdir().

You better use the fully qualified name when testing, otherwise you could get undesired behavior.

This is the way I'm reading the files form a directory and it is working perfectly.

function get_dir($path)
{
 if ($dir = opendir($path)) {
     /* This is the correct way to loop over the directory. */
     while (false !== ($file = readdir($dir)))
     {
     if (!is_dir($path.$file))
     {
     //... Your Code Here
     }
     }
     closedir($dir);
 }
 return // whatever you want to return, an array is very usefull
}

Hope this can help,
   Rodrigo
captainmike5 at hotmail dot com
22-May-2002 02:47
while working on trying to have readdir sort a listing of directories eiter alphabetically or by modification time i discovered that the readdir() function sorts very similar to the ls -Ul

maybe that will help someone.... ?
FX at yucom dot be
21-May-2002 06:16
Nice recursive code. 
It generates and displays a sorted list of all directories, sudirectories and files of your HD.

<?php
 
 
function GetFileList($path, &$a)
  {
  
$d=array(); $f=array();
  
$nd=0$nf=0;
  
$hndl=opendir($path);
   while(
$file=readdir($hndl))
   {
     if (
$file=='.' || $file=='..') continue;
     if (
is_dir($path.'\\'.$file))
      
$d[$nd++]=$file;
     else
      
$f[$nf++]=$file;
   }
  
closedir($hndl);

  
sort($d);
  
sort($f);

  
$n=1;
   for (
$i=0;$i<count($d);$i++)
   {
    
GetFileList($path.'\\'.$d[$i].'\\', $a[$n]);
    
$a[$n++][0]=$d[$i];
   }
   for (
$i=0;$i<count($f);$i++)
   {
    
$a[$n++]=$f[$i];
   }
  }

  function
ShowFileList(&$a, $N)
  {
   for (
$i=1;$i<=count($a); $i++)
     if (
is_array($a[$i]))
     {
       echo
"<H".$N.">".$a[$i][0].
              
"</H".$N.">\n";
      
ShowFileList($a[$i], $N+1);
     }
     else
       echo
"<Normal>".$a[$i].
              
"</Normal>\n";
  }

  echo (
"Thanks to FX.");
 
GetFileList("c:\\",$array);
 
ShowFileList($array, 1);
?>
fridh at gmx dot net
10-Apr-2002 08:41
Someone mentioned the infinite recursion when a symbolic link was found...

tip: is_link() is a nice function :)
slicky at newshelix dot com
21-Feb-2001 03:52
@dwalet@po-box.mcgill.ca

To search for some specific file or file extension:
Make sure that you put this expression
if (ereg("\.sql",$file)) instead of (eregi(".sql",$file)) since the ereg function is familiar with regular expressions
and "the point" (any char) represents a special reg expr. (have a look at reg expr. if you are interested!)

You can combine in the if expression whatever you want for instance if (ereg("\.sql",$file)) && (strlen($file))<100 )
:) of course this doesn't make sooo much sense to use a strlen here, but however this should only be a demonstration

Now the next thing...
Speed issue :
Since the ereg() is capable of reg expr. this means a high speed decrease for you.
So for this simple fileextension search function use the strstr() function instead... which hasn't the power of reg expr. but boast of speed
At least your "if expression" should look something like that: if(stristr($file,".sql"))
CK1 at wwwtech dot de
16-Nov-2000 10:40
funny thing ;)
if you really read your dirs with subdirs into an array like described above, and there's a link like

ln -s ./ ./recursive

you'll get an endless loop ;)
My suggestion to prevent this is to limit the number of recursion instances: Change the function to

function GetDirArray($sPath,$maxinst,$aktinst = 0)
 {
 //Load Directory Into Array
 $handle=opendir($sPath);
 while ($file = readdir($handle))
  { $retVal[count($retVal)] = $file; }

 //Clean up and sort
 closedir($handle);
 sort($retVal);

 while (list($key, $val) = each($retVal))
  {
  if ($val != "." && $val != "..")
   {
   $path = str_replace("//","/",$sPath.$val);

  if (is_dir($sPath.$val) && ($aktinst < $maxinst || $maxinst == 0))
   { GetDirArray($sPath.$val."/",$maxinst,$aktinst+1); }
   }
  }
 }

A call could be this:
$dir = GetDirArray("./",0);

Another method could be a regexp, which looks for more than $maxinst same named subdirs:

if (is_dir($sPath.$val) && !preg_match("/\/(\w+)(\/\\1){$max,}/",$sPath.$val))
 { GetDirArray($sPath.$val."/",$maxinst); }

instead of the if-construction above.