Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : Directory Functions : scandir

scandir

List files and directories inside the specified path (PHP 5)
array scandir ( string directory [, int sorting_order [, resource context]] )

Returns an array of files and directories from the directory.

Parameters

directory

The directory that will be scanned.

sorting_order

By default, the sorted order is alphabetical in ascending order. If the optional sorting_order is used (set to 1), then the sort order is alphabetical in descending order.

context

For a description of the context parameter, refer to the streams section of the manual.

Return Values

Returns an array of filenames on success, or FALSE on failure. If directory is not a directory, then boolean FALSE is returned, and an error of level E_WARNING is generated.

Examples

Example 510. A simple scandir() example

<?php
$dir    
= '/tmp';
$files1 = scandir($dir);
$files2 = scandir($dir, 1);

print_r($files1);
print_r($files2);
?>

The above example will output something similar to:

Array
(
   [0] => .
   [1] => ..
   [2] => bar.php
   [3] => foo.txt
   [4] => somedir
)
Array
(
   [0] => somedir
   [1] => foo.txt
   [2] => bar.php
   [3] => ..
   [4] => .
)


Example 511. PHP 4 alternatives to scandir()

<?php
$dir
= "/tmp";
$dh  = opendir($dir);
while (
false !== ($filename = readdir($dh))) {
   
$files[] = $filename;
}

sort($files);

print_r($files);

rsort($files);

print_r($files);

?>

The above example will output something similar to:

Array
(
   [0] => .
   [1] => ..
   [2] => bar.php
   [3] => foo.txt
   [4] => somedir
)
Array
(
   [0] => somedir
   [1] => foo.txt
   [2] => bar.php
   [3] => ..
   [4] => .
)


Notes

Tip:

You can use a URL as a filename with this function if the fopen wrappers have been enabled. See fopen() for more details on how to specify the filename and Appendix O, List of Supported Protocols/Wrappers for a list of supported URL protocols.

Related Examples ( Source code ) » scandir


Code Examples / Notes » scandir

at_he

you can separate DIRS from FILES in two arrays with a little script like :D ...
<?php
$files = scandir ( $dir ) ;
foreach( $files as $pos => $file ) {
if( is_dir( $file ) ) {

$dirs[] = $file ;
unset( $files[$pos] ) ;
}
}
?>


wwwebdesigner

using sort of scandir() that returns the content sorted by Filemodificationtime.
<?php
function scandir_by_mtime($folder) {
 $dircontent = scandir($folder);
 $arr = array();
 foreach($dircontent as $filename) {
   if ($filename != '.' && $filename != '..') {
     if (filemtime($folder.$filename) === false) return false;
     $dat = date("YmdHis", filemtime($folder.$filename));
     $arr[$dat] = $filename;
   }
 }
 if (!ksort($arr)) return false;
 return $arr;
}
?>
returns false if an error occured
otherwise it returns an array like this.
Array
(
   [20040813231320] => DSC00023.JPG
   [20040813231456] => DSC00024.JPG
   [20040814003728] => MOV00055.MPG
   [20040814003804] => DSC00056.JPG
   [20040814003946] => DSC00057.JPG
   [20040814004030] => DSC00058.JPG
   [20040814014516] => DSC00083.JPG
   [20050401161718] => album.txt
)


phdwight

Took a while to figure this:
scandir and readdir functions DOES NOT currently correctly read Japanese files.
When it encounters the Japanese characters, it just displays it as whatever character (mostly ???).
Save your braincells knowing this. Hope PHP 6 will fix this.


banzaimonkey

This script will scan a selected directory and return a list of subdirectories.  It will not return files in the list.  The subdirectories will be returned in alphabetical order.  Also, it will return only the first level of subdirectories.  This script is intended to be used in automated site navigation.
<?php
 /*
  * We'll begin the script by telling PHP which directory to look
  * at.  The path should be a string, and hence should be enclosed
  * in single quotes, such as 'home/door'
  */
 $scanthis = '.';
 
 /*
  * scandir(); will list all of the files and directories in the
  * specified directory, specified by $scanthis (above).  In this
  * line we're also initiating a new array into which we're placing
  * the results of the $scandir function so it can be processed
  * later.
  */
 $scanlisting = scandir($scanthis);
 
 /*
  * Here we create a new array to be used in the next step.  This
  * array begins empty and will be filled by way of a foreach loop
  * using values from our first array, $scanlisting.
  */
 $dirlisting = array();
 /*
  * We will run through the list and transfer all of the directory
  * names to a new array.  The "as" will indicate the variable
  * names by which we can reference the key or value in this array.
  */
 foreach($scanlisting as $key => $value){
   
   /*
    * is_dir(); will tell you whether the selected path is a
    * directory.  If it is a directory, we want to add it to our new
    * array.  
    */
   if (is_dir("$scanthis/$value") == true && $value != '.' && $value != '..'){
     
     /*
      * In order to append data to the array, we'll use empty square
      * brackets.  The name of the array is the new, empty array we.
      * just created called $dirlisting.  The value we are assigning
      * to it is the variable defined in the foreach(); function.
      */
     $dirlisting[] = $value;
   }
 }
 
 /*
  * If we want, we can output our array as a list of links.
  */
 print('<ul>');
 foreach($dirlisting as $key => $value){
   print('<li><a href="' . $scanthis . '/' . $value . '">' . $value . "</a></br></li>");
 }
 print('</ul>');
 
 /*
  * Please note that this code is not necessarily the most
  * efficient method.  However, I wanted to make things clear to a
  * beginner where things were going and how they were getting
  * there.
  */
?>


aidan

This functionality is now implemented in the PEAR package PHP_Compat.
More information about using this function without upgrading your version of PHP can be found on the below link:
http://pear.php.net/package/PHP_Compat


aryel

This function is similar to scandir, but works in PHP4. It uses readdir to get directory info.
<?php
function php4_scandir($dir,$listDirectories=false, $skipDots=true) {
$dirArray = array();
if ($handle = opendir($dir)) {
while (false !== ($file = readdir($handle))) {
if (($file != "." && $file != "..") || $skipDots == true) {
if($listDirectories == false) { if(is_dir($file)) { continue; } }
array_push($dirArray,basename($file));
}
}
closedir($handle);
}
return $dirArray;
}
?>


malmsteenforce

This function is recursive version of scandir, it scans all directories inside given directory. For instance : if we give path './dir1/' as argument , function will find also /dir1/dir2/file etc. - everything what`s inside given directory.
function scandir_recursive($path)
{
if (!is_dir($path)) return 0;
$list=array();
$directory = @opendir("$path"); // @-no error display
while ($file= @readdir($directory))
 {
      if (($file<>".")&&($file<>".."))
       {  
          $f=$path."/".$file;
$f=preg_replace('/(\/){2,}/','/',$f); //replace double slashes
if(is_file($f)) $list[]=$f;            
if(is_dir($f))
$list = array_merge($list ,scandir_recursive($f));   //RECURSIVE CALL                              
       }    
  }
@closedir($directory);  
return $list ;
}


brodseba

This function create a HTML view of a directory.  It also look for subdirectory.  I use some icon to differ from folders or files.  It's also possible to get specific icon for specific file type.
Each entrey is clickable so you can use it to populate a form field.
Have fun!
function ls_recursive2($dir)
{
 if (is_dir($dir))
 {
   $files = scandir($dir);

   foreach ($files as $file)
   {
     $currentfile = $dir . "/" . $file;

     $last_dir = "";
     // Calculate they identation.
     $count = substr_count($currentfile, '/');
     $minus_count = substr_count($_SERVER['DOCUMENT_ROOT'], '/');
     $count -= ($minus_count + 2);

     for($p = 0; $p < $count; $p++)
     {
       $last_dir .= "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
     }

     if (is_dir($currentfile))
     {
       if ($file != '.' && $file != '..')
     {
       $last_dir .= "<img src='images/folder.gif' alt='' align='middle' width='16' height='16' border='0'>&nbsp;<a href=\"javascript:go('" . $currentfile . "')\">". substr($currentfile, strrpos($currentfile, '/')) . "</a>
";
         echo $last_dir;
         ls_recursive2($currentfile);
       }
     }
     else
     {
       $last_dir .= "<img src='images/file.gif' alt='' align='middle' width='16' height='16' border='0'>&nbsp;<a href=\"javascript:go('" . $currentfile . "')\">". substr($currentfile, strrpos($currentfile, '/')) . "</a>
";
       echo $last_dir;
     }
   }
 }
}


chh

Since scandir() returns and array, here is a more concise method of dealing with the '.' and '..' problem when listing directories:
$target = '/';
$weeds = array('.', '..');
$directories = array_diff(scandir($target), $weeds);

foreach($directories as $value)
{
  if(is_dir($target.$value))
  {
     echo $value.'<br />';
  }
}


virtual

Since I needed to scan dirs and subdirs and wanted to have files and dirs not in the same var without having to explode it, I did this little function:
<?php
function scan_Dir($directory=NULL)
{
$temp = "";
if ($directory==NULL)
{
       $directory = getcwd();
}
$handle = opendir($directory);
while (false !== ($filename = readdir($handle)))
{
       if (($filename!=".") AND ($filename!=".."))
       {
               if (is_dir($directory."/".$filename))
               {
                       $old_directory = $directory;
                       $directory .= "/".$filename;
                       $temp = scan_Dir($directory);
                       $cpt = 0;
                       while ($cpt<count($temp["filename"]))
                       {
                               $arrfiles["path"][]      = $directory."/".$temp["filename"][$cpt];
                               $arrfiles["directory"][] = $directory;
                               $arrfiles["filename"][]  = $temp["filename"][$cpt];
                               $cpt++;
                       }
                       $directory = $old_directory;
               }
               else
               {
                       $arrfiles["path"][]      = $directory."/".$filename;
                       $arrfiles["directory"][] = $directory;
                       $arrfiles["filename"][]  = $filename;
               }
       }
}
return $arrfiles;
}
?>
This one seems to work properly and use multidimensional array.
To show your files, just use:
<?php
$dir2scan = "admin";
$yourvar = scan_Dir($dir2scan);
echo $yourvar["path"][0]."
"; //Complete path of the file with key 0 (dir + filename)
echo $yourvar["directory"][0]."
"; //Directory of the file with key 0
echo $yourvar["filename"][0]."
"; //Filename of the file with key 0
?>
Note that the parameter of the function is not necessary. If you don't give any, it will scan from the returned value of getcwd() function.


stan p. van de burgt

scandir() with regexp matching on file name and sorting options based on stat().
function myscandir($dir, $exp, $how='name', $desc=0)
{
   $r = array();
   $dh = @opendir($dir);
   if ($dh) {
       while (($fname = readdir($dh)) !== false) {
           if (preg_match($exp, $fname)) {
               $stat = stat("$dir/$fname");
               $r[$fname] = ($how == 'name')? $fname: $stat[$how];
           }
       }
       closedir($dh);
       if ($desc) {
           arsort($r);
       }
       else {
           asort($r);
       }
   }
   return(array_keys($r));
}
$r = myscandir('./book/', '/^article[0-9]{4}\.txt$/i', 'ctime', 1);
print_r($r);
files can be sorted on name and stat() attributes, ascending and descending:
name    file name
dev     device number
ino     inode number
mode    inode protection mode
nlink   number of links
uid     userid of owner
gid     groupid of owner
rdev    device type, if inode device *
size    size in bytes
atime   time of last access (Unix timestamp)
mtime   time of last modification (Unix timestamp)
ctime   time of last inode change (Unix timestamp)
blksize blocksize of filesystem IO *
blocks  number of blocks allocated


csaba

Scandir on steroids:
For when you want to filter your file list, or only want to list so many levels of subdirectories...
<?php
function dirList($path="", $types=2, $levels=1, $aFilter=array()) {
//  returns an array of the specified files/directories
//  start search in $path (defaults to current working directory)
//  return $types:  2 => files; 1 => directories; 3 => both;
//  $levels: 1 => look in the $path only; 2 => $path and all children;
//          3 => $path, children, grandchildren; 0 => $path and all subdirectories;
//          less than 0 => complement of -$levels, OR everything starting -$levels down
//                e.g. -1 => everthing except $path; -2 => all descendants except $path + children
//  Remaining argument(s) is(are) a filter array(list) of regular expressions which operate on the full path.
//    First character (before the '/' of the regExp) '-' => NOT.
//    First character (after a possible '-') 'd' => apply to directory name
//    The filters may be passed in as an array of strings or as a list of strings
//  Note that output directories are prefixed with a '*' (done in the line above the return)
  $dS = DIRECTORY_SEPARATOR;
  if (!($path = realpath($path?$path:getcwd()))) return array();    // bad path
  // next line rids terminating \ on drives (works since c: == c:\ on PHP).  OK in *nix?
  if (substr($path,-1)==$dS) $path = substr($path,0,-1);
  if (is_null($types)) $types = 2;
  if (is_null($levels)) $levels = 1;
  if (is_null($aFilter)) $aFilter=array();
  // last argument may be passed as a list or as an array
  $aFilter = array_slice(func_get_args(),3);
  if ($aFilter && gettype($aFilter[0])=="array") $aFilter=$aFilter[0];
  $adFilter = array();
  // now move directory filters to separate array:
  foreach ($aFilter as $i=>$filter)                  // for each directory filter...
    if (($pos=stripos(" $filter","d")) && $pos<3) {  // next line eliminates the 'd'
        $adFilter[] = substr($filter,0,$pos-1) . substr($filter,$pos);
        unset($aFilter[$i]); }
  $aFilter = array_merge($aFilter);    // reset indeces
  $aRes = array();                    // results, $aAcc is an Accumulator
  $aDir = array($path);    // dirs to check
  for ($i=$levels>0?$levels++:-1;($aAcc=array())||$i--&&$aDir;$aDir=$aAcc)
    while ($dir = array_shift($aDir))
        foreach (scandir ($dir) as $fileOrDir)
          if ($fileOrDir!="." && $fileOrDir!="..") {
              if ($dirP = is_dir ($rp="$dir$dS$fileOrDir"))
                if (pathFilter("$rp$dS", $adFilter))
                    $aAcc[] = $rp;
              if ($i<$levels-1 && ($types & (2-$dirP)))
                if (pathFilter($rp, $aFilter))
                    $aRes[] = ($dirP?"*":"") . $rp; }
  return $aRes;
}
?>
example usage:
<?php
define ("_", NULL);
// this will find all non .jpg, non .Thumbs.db files under c:\Photo
$aFiles = dirList('c:\Photo', _, 0, '-/\.jpg$/i', '-/\\\\Thumbs.db$/');
$aFiles = dirList();    // find the files in the current directory
// next lines will find .jpg files in non Photo(s) subdirectories, excluding Temporary Internet Files
set_time_limit(60);        // iterating from the top level can take a while
$aFiles = dirList("c:\\", _, 0, '/\.jpg$/i', '-d/\\\\Photos?$/i', '-d/Temporary Internet/i');
?>
See my earlier entry for the definition of pathFilter(...)
Note that this function will consume a lot of time if scanning large
directory structures (which is the reason for the '[-]d/.../' filters).
Csaba Gabor from Vienna


elbekko

Scandir function for php 3 and up.
<?php
//
// Scandir for PHP4
//
if(!function_exists('scandir'))
{
function scandir($dir, $sortorder = 0)
{
if(is_dir($dir))
{
$dirlist = opendir($dir);

while( ($file = readdir($dirlist)) !== false)
{
if(!is_dir($file))
{
$files[] = $file;
}
}

($sortorder == 0) ? asort($files) : arsort($files);

return $files;
}
else
{
return FALSE;
break;
}
}
}
?>


skatecrazy1

Scandir can be used to make directories of files not unlike apache's indexes, but CSS enabled and fully customizable:
<?
//in this example, we'll say the directory is "images"
$list = scandir("images");
$i = 0;
$num = count($list);
while($i < $num){
print "<a href=\"images/$list[$i]\">$list[$i]</a><br />";
$i++;
}
?>
That will print all the files in the "images" directory linked to the files.


dsiembab

Saw banzai monkeys code and tweaked it a little. I don't have scandir. So I had to play with the suggested use for php4.
Pretty new to PHP so beer with me. This will show your current directory as a link called "Back" and will list all of your files in a menu. I wanted this because I have a lot of static pages and needed a menu that would auto update every time I added a file.
<?php
$current=getcwd();
$directory=basename($current);
$direct=str_replace('-',' ',$directory);
$directoryuppercasewords=ucwords($direct);
/*this first section above will  get your current folder or directory and since I have a "-" between the words of my file I have to strip them to look good if I want to show the current folder or directory in the title of the first link
*/
$dir = '.';
$dh  = opendir($dir);
while (false !== ($filename = readdir($dh))) {
   $files[] =$filename;
}
$t=array_slice($files,2);
$f=array_search('index.php',$t);
/*this code above with the variable $t gets rid of the '.' and the '..' parent and ancestor files. And the variable $f finds the index file and with the code below 'unset' let you use $f as the key to get rid of that file.
*/
unset($t[$f]);
 print('<ul align="left">');
print('<li><a href="." title="'.$directoryuppercasewords.'">Back</a></br></li>');
 foreach($t as $key => $value){
$phpkill=str_replace('.php', '', $value);
$htmlkill=str_replace('.html', '', $phpkill);
$dashkill=str_replace('-',' ',$htmlkill);
$uppercasewords=ucwords($dashkill);

   print('<li><a href="' . $dir . '/' . $value . '" title="'.$uppercasewords.'>' . $uppercasewords . "</a></br></li>");
 }
 print('</ul>');
closedir($dh);
?>
I basically made all the variables so they could explain themselves, Regular expression is not my strong point right now, just becoming familiar with php functions is more of a priority, I hope this is usefull to someone.


michael from yokohama, japan

Re: phdwight comments about Japanese.
As far as I can see, readdir simply sucks up the byte stream that the OS generates and shots that at the browser. At any rate, it works fine on the PHP4 server I'm using.
The key is matching the "Content-type" headers and html / xml "encoding" values to what the OS is generating.
This gets more complex if you think of a folder that can be accessed by a samba share. The Japanese files saved from a windows client will be have the file name encoded in ShiftJIS. Any files created locally on the system would be in UTF8 (on a UTF8 system). This results in a jumbled up list of UTF8 and ShiftJIS file names in the same directory. Try displaying that on the one HTML page! It gets messy.
The real issue here is that basically any random stream of bytes is a valid file name on a linux box. Good luck!


phpfeedback dot e dot stevegs

Perhaps I'm missing something, but none of the other suggestions shown here did what I wanted.
The problem was I wanted to list all files on a hidden (ie. unreferenced) directory on my web site.  Normally, if there's no INDEX.HTM, this will happen automatically.  However, my service provider is a bit smarter: they throw up an 'unauthorised user' message in the absence of the INDEX.HTM.  The following got round the problem - if the directory contents alter, the changes are shown automatically.
Sorry about the HTML tags below - it was the only way I could get the preview to display properly.
Two files are required:
1) a blank INDEX.HTM that calls LISTFILE.PHP in a single frame:
<HTML>
<HEAD>
</HEAD>
<FRAMESET ROWS="100%" FRAMEBORDER=no BORDER=0 FRAMESPACING="0">
<FRAME src="listfile.php">
</FRAMESET></HTML>
2) a LISTFILE.PHP that lists all files and subdirectories in the current web directory (*except* the INDEX.HTM and LISTFILE.PHP files, which you know are there!)
Links to all these files are automatically created:
<HTML>
<HEAD>
</HEAD>
<BODY>
<?php
if ($handle = opendir('.')) {
 while (false !== ($file = readdir($handle)))
 {
   if ($file != "." && $file != ".." && $file != "index.htm"
     && $file != "listfile.php")
       echo "<a href=\"$file\">$file</a>
";
 }
 closedir($handle);
}
?>
</BODY></HTML>
Regards,
Steve Glennie-Smith


rich

Ok, in my previous example, you need to do the SORT after you remove the "." and ".." entries from the array.  Otherwise, you cannot start using the array at 0.
Here is corrected code:
<?php
function scandir($dir, $no_dots=FALSE) {
$files = array();
$dh  = @opendir($dir);
if ($dh!=FALSE) {
while (false !== ($filename = readdir($dh))) {
  $files[] = $filename;
}
if ($no_dots) {
while(($ix = array_search('.',$files)) > -1)
  unset($files[$ix]);
while(($ix = array_search('..',$files)) > -1)
  unset($files[$ix]);
}
sort($files);
}
return $files;
}
?>


george

Much simpler script to list all directories within a given directory, while removing the . and ..
<?php
  $mydir = dir('/path/to/directory/'); //include the trailing slash here
 
while(($file = $mydir->read()) !== false) {
$upper = ucwords($file);

    if(is_dir($mydir->path.$file)  == true && $file != '.' && $file != '..') {
        echo "<li><strong><a href='$file'>$upper</a></strong></li>";
     }
  }
  $mydir->close();
?>


reeded2002

In response to phpfeedback.e.stevegs, if you want to emulate the page displayed by an absent index completely I think this is more accurate:
<?php
   echo '<h1>Index of /adult/</h1>';
   echo '<ul>';
   echo '<li><a href="/"> Parent Directory</a></li>';
   $dir = scandir('.');
   $files = count( $dir );
   for ( $i = 0; $i < $files; $i++ )
   {
       if ( is_file($dir[$i]) )
           echo "<li><a href=\"$dir[$i]\">$dir[$i]</a></li>
";
       if ( is_dir($dir[$i]) )
           echo "<li><a href=\"$dir[$i]\"/>$dir[$i]/</a></li>
";
   }
   echo '</ul>';
?>
If the directory happens to be the root you'ld want to leave off the Parent Directory line. It's easy to apply filters to this. What I'm using filters out filenames of a certain length, any non-html and non-php files, and also various other files and directories I just dont' want being shown:
<?php
   echo '<h1>Index of /adult/</h1>';
   echo '<ul>';
   echo '<li><a href="/"> Parent Directory</a></li>';
   $dir = scandir('.');
   $files = count( $dir );
   for ( $i = 0; $i < $files; $i++ )
   {
       if ( is_file($dir[$i]) && strlen( $dir[$i] ) <= 36 && ( strstr( strtolower( $dir[$i] ), '.htm' ) ||  strstr( strtolower( $dir[$i] ), '.html' ) ||  strstr( strtolower( $dir[$i] ), '.php' ) ) )
           echo "<li><a href=\"$dir[$i]\">$dir[$i]</a></li>
";
       if ( is_dir($dir[$i])  && $dir[$i] != "." && $dir[$i] != ".." && $dir[$i] != "adult" )
           echo "<li><a href=\"$dir[$i]\"/>$dir[$i]/</a></li>
";
   }
   echo '</ul>';
?>


bosmans koen

in addition to "brodseba at brodseba dot com" from march 2005:
Perfected the script to sort files and directories
in natural alphabetic order and with files listed first.
Also added a more relative directory path approach.
And changed the javascripting for links in simple ordinary href's.
Note that the script uses scandir from the pear package
(since I'm obliged to use an older PHP version).
<?
// scandir function is for php 5.0
require_once '\pear\PHP\Compat\Function\scandir.php';
// sorting function
// based on counting of dots
function cmp($a, $b) {
if ( substr_count($a,".") ==  substr_count($b,".") ) {
if ( is_string($a) && is_string($b) ) {
return strcasecmp($a, $b) > 0 ? 1 : -1;
}elseif ( is_int($a) && is_int($b) ) {
return $a > $b ? 1 : -1;
}elseif ( is_int($a) && is_string($b) ) {
return 1;
}elseif ( is_string($a) && is_int($b) ) {
return -1;
}else {
return 0;
}}
return substr_count($a,".") <  substr_count($b,".") ? 1 : -1;
}
function ls_recursive2($dir) {
if (is_dir($dir)) {
$files = scandir($dir);
// needed to sort array
usort ($files, "cmp");
foreach ($files as $file) {
$currentfile = $dir . "/" . $file;
$last_dir = "";
// calculate the identation.
$count = substr_count($currentfile, '/');
$minus_count = substr_count($_SERVER['SCRIPT_FILENAME'], '/');
$count -= ($minus_count +1);
for($p = 0; $p < $count; $p++) {
$last_dir .= "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
}
// output with calculated identation
// first in case of directories
// run function again for directory
if (is_dir($currentfile)) {
if ($file != '.' && $file != '..') {
$sub_len = strlen(dirname($_SERVER['SCRIPT_FILENAME']))+1;
$java_targ = substr($currentfile, $sub_len);
$last_dir .= "&nbsp;&nbsp;<img src='folder.png'
alt='' align='middle' border='0'>&nbsp;
<a href=".$java_targ.">".$java_targ ."</a>
\n";
echo $last_dir;
ls_recursive2($currentfile);
}
// if not a directory, then files in current directory
} else {
$sub_len = strlen(dirname($_SERVER['SCRIPT_FILENAME']))+1;
$java_targ = substr($currentfile, $sub_len);
$last_dir .= "<img src='file.png'
alt='' align='middle' border='0'>&nbsp;
<a href=".$java_targ.">".$java_targ."</a>
\n";
echo $last_dir;
}}}}
?>
<?
$this = dirname($_SERVER['SCRIPT_FILENAME']);
echo $this."
\n";
ls_recursive2($this);
?>
**
ps: I can take a comment, even some criticism,
but do understand: I'm fairly new at this.


welshwizard

Im wanting to when php executed for the script to scan for certain file extensions in a windows mapped out folder which is set as H:\ when a user logs on.
Will the php scan locally (the linux box) or will it work client side like i want?

thnks
Mat


beingmrkenny

I wrote this function to read a folder and place all the folders and sub folders it contains into an array.
<?php
// Initialise empty array, otherwise an error occurs
$folders = array();
function recursive_subfolders($folders) {
// Set path here
$path = '/path/to/folder';

// Create initial "Folders" array
if ($dir = opendir($path)) {
$j = 0;
while (($file = readdir($dir)) !== false) {
if ($file != '.' && $file != '..' && is_dir($path.$file)) {
$j++;
$folders[$j] = $path . $file;
}
}
}

closedir($dir);

// Then check each folder in that array for subfolders and add the subfolders to the "Folders" array.
$j = count($folders);
foreach ($folders as $folder) {
if ($dir = opendir($folder)) {
while (($file = readdir($dir)) !== false) {
$pathto = $folder. '/' . $file;
if ($file != '.' && $file != '..' && is_dir($pathto) && !in_array($pathto, $folders)) {
$j++;
$folders[$j] = $pathto;
$folders = recursive_subfolders($folders);
}
}
}
closedir($dir);
}

sort($folders);
return $folders;
}
$folders = recursive_subfolders($folders);
?>
$folders now contains an array with the full paths to each subfolder. E.g.:
Array
(
   [0] => /path/to/folder/dir1
   [1] => /path/to/folder/dir1/subdir
   [2] => /path/to/folder/dir1/subdir/subsubdir
   [3] => /path/to/dolfer/dir2
)
This function has only been tested on Linux.


www.mdsjack.bo.it

I would like to share a couple of functions I've made to get an Array of files of a certain extension inside a Directory.
<?php
// Firstly, a PHP 5 emulation
function php4_scandir($dir, $sort = 0)
{
if (PHP_VERSION >= '5') return scandir($dir, $sort);

$dirmap = array();

if(!is_dir($dir))
{
trigger_error("lib::scandir($dir): failed to open dir: Invalid argument", E_USER_WARNING);
return false;
}

$dir = opendir($dir);

while (false !== ($file = readdir($dir)))
$dirmap[] = $file;

closedir($dir);

($sort == 1) ? rsort($dirmap) : sort($dirmap);

return $dirmap;
}
/*
Then, this one converts directory files into array items.
It also can filter by file extension.
*/
function dir2arr($dir, $ext = null)
{
$arr = array();

if(PHP_VERSION >= '4.3.0')
{
# PHP 4.3.0 code
if ($dir = glob("$dir*".(!$ext ? '.*' : '{'.$ext.', '.strtoupper($ext).'}'), GLOB_NOSORT + GLOB_BRACE))
foreach ($dir as $file)
$arr[] = preg_replace("#(?:.+\/{1})*([^\.]+)\.(.+)#i", '$1', $file);
}
else
{
# PHP 4.2.x code
$dir = php4_scandir($dir); // See code snippet above
if(!$ext) $ext = '\.[a-z]+';
$pattern = "#([^\.|\.\.$]+)$ext#i";
foreach ($dir as $file)
if (preg_match($pattern, $file, $filename))
$arr[] = $filename[1];
}

return (empty($arr) ? false : $arr);
}
?>


pablo dot fabregat

i was triyng to do something similar to the ls -R command in linux, so, using the functions from csaba , i could, so, using this simple lines, you'll get that result:
<?php
$directory = "."; // for the actual directory
$directories = dirList($directory, 2, 0); // this calls the csaba's function dirlist, wich has type 2(files) and level 0($path and all subdirectories) as parameters. And it will return an array with all the returned paths
//so i cross all over the array doing an echo for every single item of the array
foreach ($directories as $dir){
echo $dir."
";
}
?>
and that's it, remember that you need the functions listed above from csaba to use this


progrium+php

I made this to represent a directory tree in an array that uses the file or directory names as keys and full paths as the value for files. Directories are nested arrays.
<?php
function generatePathTree($rootPath) {
   $pathStack = array($rootPath);
   $contentsRoot = array();
   $contents = &$contentsRoot;
   while ($path = array_pop($pathStack)) {
      $contents[basename($path)] = array();
      $contents = &$contents[basename($path)];
      foreach (scandir($path) as $filename) {
          if ('.' != substr($filename, 0, 1)) {
              $newPath = $path.'/'.$filename;
              if (is_dir($newPath)) {
                  array_push($pathStack, $newPath);
                  $contents[basename($newPath)] = array();
              } else {
                  $contents[basename($filename)] = $newPath;
              }
          }
      }
   }
return $contentsRoot[basename($rootPath)];
}
?>
The function will return something like this:
Array
(
   [index.php] => /usr/local/www/index.php
   [js] => Array
       (
           [async.js] => /usr/local/www/js/async.js
           [dom.js] => /usr/local/www/js/dom.js
           [effects.js] => /usr/local/www/js/effects.js
           [prototype.js] => /usr/local/www/js/prototype.js
       )
   [logo.png] => /usr/local/www/logo.png
   [server.php] => /usr/local/www/server.php
   [test.js] => /usr/local/www/test.js
)


colabus

I made a small dir listing based on file modification date, could find alot on this myself so I hope this helps someone.
<?
$dirView="./blah";
$dirFiles=scandir($dirView);

$cwdName=array(); $cwdMod=array(); $whatWeNeed=array();

// Parallel arrays (ignore the ".", ".." and inturn hidden files
foreach ($dirFiles as $data)
{
if (!preg_match('/^\./', $data))
{
$cwdName[]=$data;
$cwdMod[]=filemtime($dirView."/".$data);
}
}

// Merge and sort
$mergeArray=array_combine($cwdMod, $cwdName);
krsort($mergeArray, SORT_NUMERIC);

// Build new array
foreach ($mergeArray as $key => $value)
{
$whatWeNeed[]=$value;
}

// Some maintainence
unset($dirFiles, $cwdName, $cwdMod, $mergeArray);
# Then can grab latest changed file/folder with whatWeNeed[0] and so on..
?>
Tested with error_reporting(E_ALL); and PHP5.1


carlfredrik dot bowin

I made a function that scans the directory and all it subfolders. You can also sort them with folders first and files after, in alphabetic order. It works with both PHP 4 and 5.
<?php
function rec_scandir($dir)
{
   $files = array();
   if ( $handle = opendir($dir) ) {
       while ( ($file = readdir($handle)) !== false ) {
           if ( $file != ".." && $file != "." ) {
               if ( is_dir($dir . "/" . $file) ) {
                   $files[$file] = rec_scandir($dir . "/" . $file);
               }else {
                   $files[] = $file;
               }
           }
       }
       closedir($handle);
       return $files;
   }
}
function cmp($a, $b)
{
   if ( is_string($a) && is_string($b) ) {
       return strcmp($a, $b) > 0 ? 1 : -1;
   }elseif ( is_int($a) && is_int($b) ) {
       return $a > $b ? 1 : -1;
   }elseif ( is_int($a) && is_string($b) ) {
       return 1;
   }elseif ( is_string($a) && is_int($b) ) {
       return -1;
   }else {
       return 0;
   }
}
function array_ukmultisort(&$arr, $func) {
   uksort($arr, $func);
   while ( list($key, $val) = each($arr) ) {
       if ( is_array($val) ) {
           array_ukmultisort($arr[$key], $func);
       }
   }
}
$dir = rec_scandir(".");
array_ukmultisort($dir, "cmp");
echo "<pre>";
print_r($dir);
echo "</pre>";
?>


sk3391

Here is a little script that i through together to count the files in my directory while excluding the "."  i hope it helps you out!
<?
$dir = ".";
$sort = 0;
  $dir_open = @ opendir($dir);
 
  while (($dir_content = readdir($dir_open)) !== false)
          $files[] = $dir_content;
 
  if ($sort == 1) {
      rsort($files, SORT_STRING);
} else {
      sort($files, SORT_STRING);
}
$a=0;
$b=10;
$file_s="";
while($a < $b) {
 
$c=1;
$d=5;
while($c < $d) {
$dot[$c.",".$a]=str_repeat(".", $c);
if($files[$a] == $dot[$c.",".$a]) {
unset($files[$a]);
} else {
}
$c++;
}
if($files[$a] != "") {
$brake[$a]="
";
} else {
$brake[$a]="";
}
$file_s.=$files[$a].$brake[$a];
$a++;
}
echo $file_s;
echo "
";
echo count($files);
?>


anders dot jenbo

greg at sasses dot net posted a function for php versions befor 5, but it still contained a few mistakes so here is a more accurate version.
if(!function_exists('scandir')) {
   function scandir($dir, $sortorder = 0) {
       if(is_dir($dir) && $dirlist = @opendir($dir)) {
           while(($file = readdir($dirlist)) !== false) {
               $files[] = $file;
           }
           closedir($dirlist);
           ($sortorder == 0) ? asort($files) : rsort($files); // arsort was replaced with rsort
           return $files;
       } else return false;
   }
}


trevi55

For non php5-users here you are this function...
It isn't set the wrapper, but I think it's enough :P.
If no pararameter is set, the scandir() function will scan the local file directory.
Set the optional parameter "$sort" to 1 to reverse the alphabetical-sorting.
<?
function scandir($dir = './', $sort = 0)
{

$dir_open = @ opendir($dir);

if (! $dir_open)
return false;


while (($dir_content = readdir($dir_open)) !== false)
$files[] = $dir_content;

if ($sort == 1)
rsort($files, SORT_STRING);
else
sort($files, SORT_STRING);

return $files;
}
?>


pawel dlugosz

For directory containing files like (for example) -.jpg the results of scandir are a little "weird" ;)
<?php
 
  $dir = '/somedir';
  $files = scandir($dir);
  print_r($files);
?>
Array
(
   [0] => -.jpg
   [1] => .
   [2] => ..
   [3] => foo.txt
   [4] => somedir
)
Beware - sorting is in ASCII order :)


skyeye

dirlst - function to get directory and subdirectory file listing. Function outputs
an array with filenames and optionally also their mod.time and/or size.
You can choose also whether to include subdirectory names into listing
Function returns number of files listed.
$srcdir - source directory (without ending slash)
$fs - output array
$p - position of relative path, usually $p = strlen($srcdir) + 1;
set to 0 to store absolute path
$getfmt - set to 1 to include filemodtime in output
$getfsz - set to 1 to include filesize in output
$getdrs - set to 1 to include subdirectory names in output
$verbose - set to 1 to display output in runtime
Usage example.
Get directory listing (files only) and save it into a file:
$srcdir = 'C:\SomeFolder';
dirlst($srcdir, $files, strlen($srcdir) + 1, 1, 1, 0, 0);
file_put_contents($filename, join("", $files));
Get listing from file and explode contents:
$files = file($fn);
foreach($files as $line) {
 list($file,$fmt,$fsz)=explode('|',$line);
 ...
}
<?php
function dirlst($srcdir, &$fs, $p=0, $getfmt=0, $getfsz=0, $getdrs=0, $verbose=0) {
 $num = 0;
 if(($files = scandir($srcdir))!==false) {    
   foreach($files as $file) {
     if($file != '.' && $file != '..') {
       $srcfile = $srcdir . '\\' . $file;    
       $sf = substr($srcfile,$p);
       $sst = stat($srcfile);
       if($getfmt) { $fmt = $sst['mtime']; $sf.='|'.$fmt; }
       if($getfsz) { $fsz = $sst['size']; $sf.='|'.$fsz; }
       if(is_file($srcfile)) {
         $fs[] = $sf."|\n";
         if($verbose) echo $sf."|\n";                            
       }
       else if(is_dir($srcfile)) {
         if($getdrs) { $fs[] = $sf."|\n"; if($verbose) echo $sf."|\n"; }
         $num += dirlst($srcfile, $fs, $p, $getfmt, $getfsz, $getdrs, $verbose);
       }
     }
   }
 }
 return $num;
}
?>
dirsort - function to sort directory listing array. Function returns sorted array.
$fs - sortable array (got by dirlst())
$col - column to sort; if the listing contains filename, filemodtime and filesize,
then: 0 - files, 1 - mod.time, 2 - size
$dsc - set to 0 to sort ascending, 1 - to sort descending
Usage example.
Sort by size, ascending:
$fs = dirsort($fs, 2, 0);
<?php
function dirsort($fs, $col=0, $dsc=0) {
 foreach($fs as $line) list($col0[],$col1[],$col2[]) = explode('|',$line);
 if($col==0) {
   natcasesort($col0); if($dsc) $col0=array_reverse($col0,1);
   $keys = array_keys($col0);
 }
 if($col==1) {
   if($dsc) arsort($col1); else asort($col1);
   $keys = array_keys($col1);
 }
 if($col==2) {
   if($dsc) arsort($col2); else asort($col2);
   $keys = array_keys($col2);
 }
 foreach($keys as $k) $nfs[] = $fs[$k];
 return $nfs;
}
?>


deryckchan

Bear in mind that sorting is *always* performed when scandir() is called. String sorting takes O(|s|n log n) runtime, and this adds to the burden of the server's memory and processing power.
Therefore, whenever the alphabetical order of the directory content is unimportant, especially if sorting is to be performed by another order, or the natural order of the files on the filesystem is to be utilized, the use of opendir(), readdir() and closedir() combined is always preferred to scandir().


edwin

Aryel wrote a function called php4_scandir which works only if the is_dir function is called with the complete path. Otherwise the function will only work within the current working directory. So changing is_dir($file) to is_dir("$dir/$file") will work.
I believe that the test on skipDots should be negated to get the desired effect.


csaba

A nice way to filter the files/directories you get back from scandir:
<?php
function pathFilter ($path, $aFilter) {
  // returns true iff $path survives the tests from $aFilter
  // $aFilter is an array of regular expressions: [-]/regExp/modifiers
  // if there is a leading '-' it means exclude $path upon a match (a NOT test)
  // If the first expression has a leading '-', $path is in, unless it gets excluded.
  // Otherwise, $path is out, unless it gets included via the filter tests.
  // The tests are applied in succession.
  // A NOT test is applied only if $path is currently (within the tests) included
  // Other tests are applied only if $path is currently excluded.  Thus,
  // array("/a/", "-/b/", "/c/") => passes if $path has a c or if $path has an a but no b
  // array("/a/", "/c/", "-/b/") => passes if $path has an a or c, but no b
  // array("-/b/", "/a/", "/c/") => passes if $path has no b, or if $path has an a or c
  if (!$aFilter) return true;           // automatic inclusion (pass) if no filters
  foreach ($aFilter as $filter) break;  // we don't know how it's indexed
  $in = $filter[0]=="-";                // initial in/exclusion based on first filter
  foreach ($aFilter as $filter)         // walk the filters
     if ($in==$not=($filter[0]=="-"))   //     testing only when necessary
        $in ^= preg_match(substr($filter,$not),$path);    // flip in/exclusion upon a match
  return $in;
}
?>
Csaba Gabor from Vienna


evert_18

A nice function to read a dir, with unlimited subdirs and files, it will create an array with files and dirs (tree structure).
<?php
function dirlist($dir) {
foreach(scandir($dir) as $entry)
if($entry != '.' && $entry != '..')
{
$entry  = $dir.'/'.$entry;
if(is_dir($entry))
{
$path = pathinfo($entry);
$listarray[$path['basename']] = dirlist($entry);
}
else
{
$path = pathinfo($entry);
$listarray[] = $path['basename'];
}
}
return($listarray);
}
?>


greg

A minor revision to elbekko at gmail dot com <PHP5 scandir function. The arsort should be rsort. Here is the complete function with the correction:
<?php
if(!function_exists('scandir')) {
  function scandir($dir, $sortorder = 0) {
      if(is_dir($dir))        {
          $dirlist = opendir($dir);
          while( ($file = readdir($dirlist)) !== false) {
              if(!is_dir($file)) {
                  $files[] = $file;
              }
          }
          ($sortorder == 0) ? asort($files) : rsort($files); // arsort was replaced with rsort
          return $files;
      } else {
      return FALSE;
      break;
      }
  }
}
?>


yassin ezbakhe
/**********************************************
*
*   PURPOSE: List files inside the specified path and its
*   subdirectories
*
*   array scandir_recursive (string dir)
*
*   This function will return a multidimensional array
*   that represents main folder's tree structure.
*   Each folder has its own named array
*
**********************************************/
function scandir_recursive($directory)
{
   $folderContents = array();
   $directory = realpath($directory).DIRECTORY_SEPARATOR;
   foreach (scandir($directory) as $folderItem)
   {
       if ($folderItem != "." AND $folderItem != "..")
       {
           if (is_dir($directory.$folderItem.DIRECTORY_SEPARATOR))
           {
               $folderContents[$folderItem] = scandir_recursive( $directory.$folderItem."\\");
           }
           else
           {
               $folderContents[] = $folderItem;
           }
       }
   }
   return $folderContents;
}


Change Language


Follow Navioo On Twitter
chdir
chroot
dir
closedir
getcwd
opendir
readdir
rewinddir
scandir
eXTReMe Tracker