PHP
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

Fileinfo> <Directory Functions
Last updated: Fri, 22 Aug 2008

view this page in

scandir

(PHP 5)

scandirList files and directories inside the specified path

Description

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 #1 A simple scandir() example

<?php
$dir    
'/tmp';
$files1 scandir($dir);
$files2 scandir($dir1);

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 #2 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

A URL can be used 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 List of Supported Protocols/Wrappers for a list of supported URL protocols.



Fileinfo> <Directory Functions
Last updated: Fri, 22 Aug 2008
 
add a note add a note User Contributed Notes
scandir
webmaster at asylum-et dot com
23-Jul-2008 03:50
<?php
/**
 * outputs all files and directories
 * recursively starting with the given
 * $base path. This function is a combination
 * of some of the other snips on the php.net site.
 * All are good but lacked one thing or another
 * that I needed like .htaccess
 * files get excluded with the one that checks to
 * see if the first character is a . and omits
 * that.
 *
 * @example rscandir(dirname(__FILE__).'/'));
 * @param string $base
 * @param array $omit
 * @param array $data
 * @return array
 */
function rscandir($base='', &$data=array()) {
 
 
$array = array_diff(scandir($base), array('.', '..')); # remove ' and .. from the array */
  
 
foreach($array as $value) : /* loop through the array at the level of the supplied $base */
 
   
if (is_dir($base.$value)) : /* if this is a directory */
     
$data[] = $base.$value.'/'; /* add it to the $data array */
     
$data = rscandir($base.$value.'/', $data); /* then make a recursive call with the
      current $value as the $base supplying the $data array to carry into the recursion */
     
   
elseif (is_file($base.$value)) : /* else if the current $value is a file */
     
$data[] = $base.$value; /* just add the current $value to the $data array */
     
   
endif;
   
  endforeach;
 
  return
$data; // return the $data array
 
}

echo
'<pre>'; var_export(rscandir(dirname(__FILE__).'/')); echo '</pre>';
/*
Output:
array (
  0 => '/path/to/web/.htaccess',
  1 => '/path/to/web/foo/',
  2 => '/path/to/web/foo/file.txt'
)
*/
?>
Oleg Svarog
25-Jun-2008 03:41
Some modifications of Daniel's code:
the task before me had such a requirement - to show the folder structure in array as follows

[0] => array
     {
         [name]=>'smth',
         [path] =>'smth',
         [sub] => array
                      {
                         [0] =>
                         [1] =>
                         ...
                      }
      }
[1] => array
     {
         [name]=>'smth',
         [path] =>'smth',
         [sub] => array
                      {
                         [0] =>
                         [1] =>
                         ...
                      }
      }
...

All the structure will be deposited in $allData array

<?php
/**
         * returns the folder content names
         *
         * @param string $rootDir path to the root folder
         * @param array $allowext allowed extensions
         * @param array $notallownames not allowed names
         * @param array $allData array by reference which collects the root content
         */
       
static function ScanDirectories($rootDir, $allowext, $notallownames, &$allData)
        {
             
$dirContent = scandir($rootDir);
              static
$i=0;
            foreach(
$dirContent as $key => $content)
            {
                if (
$content == '.' || $content == '..') continue;
               
$path = $rootDir . SEPARATOR . $content;
               
$ext = substr($content, strrpos($content, '.') + 1);
                if(
in_array($ext, $allowext) && is_file($path) && is_readable($path) && !in_array($content, $notallownames))
                {
                   
$allData[$i][name] = $content;
                   
$allData[$i][path] = $rootDir;
                   
$allData[$i][sub] = '';
                }
                else if(
is_dir($path) && is_readable($path) && !in_array($content, $notallownames))
                {
                   
$allData[$i][name] = $content;
                   
$allData[$i][path] = $rootDir;
                   
$allData[$i][sub] = array();
                  
                   
self::scanDirectories($path, $allowext, $notallownames, &$allData[$i][sub]);
                }
               
$i++;
            }
        }
?>
Ximin Luo
06-Jun-2008 06:47
krom: that approach doesn't work, since eg. '#' sorts *before* '.' in the ASCII sorting order. you need to compare values.

also, russel, you don't need to do substr($value, 0, 1) - $value[0] works fine.
russell at russellfinlay dot com
14-May-2008 03:14
A little snippet of code that will remove any files beginning with '.'

Good for removing '.' and '..' as well as any other hidden files.

Resulting array is $files

<?php

$dir
= '.';
$files = scandir($dir);

foreach(
$files as $i => $value) {

        if (
substr($value, 0, 1) == '.') {
                unset(
$files[$i]);
        }
}

?>
Daniel
12-Apr-2008 02:55
recursive callback "scanDirectories" did not work for me. So I changed it to:

function scanDirectories($rootDir, $allowext, &$allData = array()) {
    $dirContent = scandir($rootDir);
    foreach($dirContent as $key => $content) {
        if ($content == '.' || $content == '..') continue;
        $path = $rootDir . DIRECTORY_SEPARATOR . $content;
        $ext = substr($content, strrpos($content, '.') + 1);
        if(in_array($ext, $allowext) && is_file($path) && is_readable($path)) {
            $allData[] = $path;
        }
        else if(is_dir($path) && is_readable($path)) {
            // recursive callback to open new directory
            scanDirectories($path, $allowext, $allData);
        }
        // else unreadable hell
    }
    return $allData;
}
krom
03-Apr-2008 11:37
You could also simply remove the first two entries in the returned array, if it is an array and contains more than two entries. (if it contains only two entries, you have an empty directory)
Since at least for windows and linux every directory contains '.' and '..', which will be the first two entries in the returned array. Correct me if i'm wrong.

$files = scandir($myDir);
if (is_array($files) && sizeof($files) > 2)  {
    unset($files[0]);
    unset($files[1]);
    // reindex, if needed
    $files = array_values($files);
    // work with rest of array
    // ...
}

Obviously remove the last two entries, if you sorted it the other way around.

Regards,
krom
swaitch
21-Mar-2008 12:26
This script worked perfectly for me in removing the . and .. plus made the files into links for quick viewing. Might be handy.
<?php
$dir
= '../quickhelp/Accounts'; // Your Directory
$files = scandir($dir, 0);
for(
$ctr = 1; $ctr < sizeof( $files ); $ctr++ ) {
    if(
$files[$ctr] != "." && $files[$ctr] != "..")
print
"<li><a href='Accounts/$files[$ctr]' target='viewer'>$files[$ctr]</a></li>";
}
?>
Mechkurt
11-Mar-2008 12:39
foreach(scandir('.') as $f) {
 if ($f[0]=='.') continue;
 //Do your dirty work code monkey
}

Actualy if you do that, you could skip files that do start with a dot (like .htaccess for example)...

File name comparaison with '.' and '..' could seem dirty but for me it does the job ;-)
asamir at asamir dot net
05-Mar-2008 07:21
This is a modification of scanDirectories function that generates a list of all files in the chosen directory and all subdirectories of specific extentions $allowext

<?php
function scanDirectories($rootDir, $allowext, $allData=array()) {
   
$dirContent = scandir($rootDir);
    foreach(
$dirContent as $key => $content) {
       
$path = $rootDir.'/'.$content;
       
$ext = substr($content, strrpos($content, '.') + 1);
       
        if(
in_array($ext, $allowext)) {
            if(
is_file($path) && is_readable($path)) {
               
$allData[] = $path;
            }elseif(
is_dir($path) && is_readable($path)) {
               
// recursive callback to open new directory
               
$allData = scanDirectories($path, $allData);
            }
        }
    }
    return
$allData;
}

$rootDir = "www";
$allowext = array("zip","rar","html");
$files_array = scanDirectories($rootDir,$allowext);
print_r($files_array);
?>
Anonymous
28-Feb-2008 03:09
The easiest way to skip 'hidden' folders and the obtrusive '..' & '.' is like so

foreach(scandir('.') as $f) {
 if ($f[0]=='.') continue;
 //Do your dirty work code monkey
}

I haven't seen anyone use this simple solution so far so I thought I'd share it
SlowWalkere at gmail dot com
15-Feb-2008 07:22
Just noticed a minor difference between scandir and readdir.

When opening a directory and using readdir(), each file appears to be accessed in the process.  This resets the "Last Accessed" time that you would get with fileatime().

With scandir(), the list is created and none of the files are accessed.  Therefore the access times remain unchanged.

I encountered this while writing a script to scan a directory and delete any file that hadn't been accessed in x time.  Kind of defeated the purpose when the directory listing accessed every file...
fatpratmatt dot at dot gmail dot com
27-Dec-2007 07:28
This function generates a list of all files in the chosen directory and all subdirectories, throws them into a NON-multidimentional array and returns them.

Most of the recursive functions on this page only return a multi-dimensional array.

This is actually a modification of some one else's function (thanks mail at bartrail dot de ;])

<?php
function scanDirectories($rootDir, $allData=array()) {
   
// set filenames invisible if you want
   
$invisibleFileNames = array(".", "..", ".htaccess", ".htpasswd");
   
// run through content of root directory
   
$dirContent = scandir($rootDir);
    foreach(
$dirContent as $key => $content) {
       
// filter all files not accessible
       
$path = $rootDir.'/'.$content;
        if(!
in_array($content, $invisibleFileNames)) {
           
// if content is file & readable, add to array
           
if(is_file($path) && is_readable($path)) {
               
// save file name with path
               
$allData[] = $path;
           
// if content is a directory and readable, add path and name
           
}elseif(is_dir($path) && is_readable($path)) {
               
// recursive callback to open new directory
               
$allData = scanDirectories($path, $allData);
            }
        }
    }
    return
$allData;
}
?>

Example output:

print_r(scanDirectories("www"));
---
Array
(
    [0] => www/index.php
    [1] => www/admin.php
    [3] => www/css/css.css
    [4] => www/articles/2007/article1.txt
    [4] => www/articles/2006/article1.txt
    [8] => www/img/img1.png
)
mail at bartrail dot de
21-Nov-2007 04:39
Here's another little function to scan a directory and it's file contents width scandir() including a little file filter..
<?php
/**
 * Recursive function to scan a directory with * scandir() *
 *
 * @param String $rootDir
 * @return multi dimensional array
 */
function scanDirectories($rootDir) {
   
// set filenames invisible if you want
   
$invisibleFileNames = array(".", "..", ".htaccess", ".htpasswd");
   
// run through content of root directory
   
$dirContent = scandir($rootDir);
   
$allData = array();
   
// file counter gets incremented for a better
   
$fileCounter = 0;
    foreach(
$dirContent as $key => $content) {
       
// filter all files not accessible
       
$path = $rootDir.'/'.$content;
        if(!
in_array($content, $invisibleFileNames)) {
           
// if content is file & readable, add to array
           
if(is_file($path) && is_readable($path)) {
               
$tmpPathArray = explode("/",$path);
               
// saving filename
               
$allData[$fileCounter]['fileName'] = end($tmpPathArray);
               
// saving while path (for better access)
               
$allData[$fileCounter]['filePath'] = $path;
               
// get file extension
               
$filePartsTmp = explode(".", end($tmpPathArray));
               
$allData[$fileCounter]['fileExt'] = end($filePartsTmp);
               
// get file date
               
$allData[$fileCounter]['fileDate'] = filectime($path);
               
// get filesize in byte
               
$allData[$fileCounter]['fileSize'] = filesize($path);
               
$fileCounter++;
           
// if content is a directory and readable, add path and name
           
}elseif(is_dir($path) && is_readable($path)) {
               
$dirNameArray = explode('/',$path);
               
$allData[$path]['dirPath'] = $path;
               
$allData[$path]['dirName'] = end($dirNameArray);
               
// recursive callback to open new directory
               
$allData[$path]['content'] = scanDirectories($path);
            }
        }
    }
    return
$allData;
}
?>
cHH
05-Nov-2007 12:46
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 />';
   }
}
deryckchan at gmail dot com
30-Aug-2007 10:44
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().
george at REMOVE-THIScommentsville dot com
30-Aug-2007 02:27
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();
?>
Anders dot Jenbo at Pc dot DK
10-Jul-2007 06:59
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;
    }
}
dsiembab at fullchannel dot net
28-Jun-2007 03:51
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
08-Jun-2007 04:43
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!
Edwin at NOSPAM dot example dot com
29-May-2007 08:46
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.
phdwight at yahoo dot com
20-Mar-2007 01:27
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 at gmail dot com
17-Mar-2007 11:24
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.
   */
?>
aryel at redtwilight dot com dot br
07-Feb-2007 02:07
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;
}
?>
evert_18 at hotmail dot com
14-Dec-2006 10:38
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);
}
?>
SkyEye
30-Nov-2006 05:37
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;
}

?>
reeded2002 at mypacks dot net
27-Oct-2006 12:54
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><br>";

        if (
is_dir($dir[$i]) )
            echo
"<li><a href=\"$dir[$i]\"/>$dir[$i]/</a></li><br>";
    }

    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><br>";

        if (
is_dir($dir[$i])  && $dir[$i] != "." && $dir[$i] != ".." && $dir[$i] != "adult" )
            echo
"<li><a href=\"$dir[$i]\"/>$dir[$i]/</a></li><br>";
    }

    echo
'</ul>';
?>
phpfeedback dot e dot stevegs at spamgourmet dot com
15-Aug-2006 10:18
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><br>";
  }
 
closedir($handle);
}
?>
 </BODY></HTML>

Regards,

Steve Glennie-Smith
beingmrkenny at gmail dot com
13-Aug-2006 02:41
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.
at_he at hotma1l dot com
10-Aug-2006 03:50
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] ) ;
    }
}

?>
malmsteenforce at tlen dot pl
19-Jul-2006 03:55
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 ;
}
greg at sasses dot net
19-May-2006 03:27
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;
       }
   }
}
?>
elbekko at gmail dot com
08-Apr-2006 07:34
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;
        }
    }
}
?>
www.mdsjack.bo.it
07-Apr-2006 02:54
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