文字

scandir

(PHP 5, PHP 7)

scandir列出指定路径中的文件和目录

说明

array scandir ( string $directory [, int $sorting_order [, resource $context ]] )

返回一个 array ,包含有 directory 中的文件和目录。

参数

directory

要被浏览的目录

sorting_order

默认的排序顺序是按字母升序排列。如果使用了可选参数 sorting_order(设为 1),则排序顺序是按字母降序排列。

context

context 参数的说明见手册中的 Streams API 一章。

返回值

成功则返回包含有文件名的 array ,如果失败则返回 FALSE 。如果 directory 不是个目录,则返回布尔值 FALSE 并生成一条 E_WARNING 级的错误。

更新日志

版本 说明
5.4.0 sorting_order now accepts constants. Any nonzero value caused descending order in previous versions.

范例

Example #1 一个简单的 scandir() 例子

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

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

以上例程的输出类似于:

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

Example #2 scandir() 在 PHP 4 中的实现

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

sort ( $files );

print_r ( $files );

rsort ( $files );

print_r ( $files );

?>

以上例程的输出类似于:

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

注释

Tip

如已启用fopen 包装器,在此函数中, URL 可作为文件名。关于如何指定文件名详见 fopen() 。各种 wapper 的不同功能请参见 支持的协议和封装协议,注意其用法及其可提供的预定义变量。

参见

  • opendir() - 打开目录句柄
  • readdir() - 从目录句柄中读取条目
  • glob() - 寻找与模式匹配的文件路径
  • is_dir() - 判断给定文件名是否是一个目录
  • sort() - 对数组排序

用户评论:

[#1] sharshun dot aliaksandr at gmail dot com [2015-11-04 02:24:54]

<?php

function glob_recursive($pattern$flags 0){
// forked from https://github.com/rodurma/PHP-Functions/
    // blob/master/glob_recursive.php
  
$files glob($pattern$flags);
       
  foreach (
glob(dirname($pattern).'**");
    
$arr=array_unique(array_merge($a$ar));

    foreach (
$arr as $v) {
        if (
is_dir($v)) {
            
$arra[0][]=$v.'/';
        } else {
            
$arra[1][]=$v;
        }
    }
    
sort($arra);
    return 
$arra;
}
$a=dirInfoReGet('c:/test_directory/');
print_r($a);

?>


http://i.stack.imgur.com/H7UF3.jpg

Best regards.

[#2] telefoontoestel59 at hotmail dot com [2015-07-01 14:12:14]

I was looking for an easy way to get only files from a certain directory. I came up with the following line of code that will result in an array listing only files. the samen can be done for directories ofcourse.

<?php
$files 
array_filter(scandir($directory), function($file) { return is_file($file); })
?>

[#3] Tom [2015-01-24 16:01:53]

Just was curious to count files and lines in a project

<?php

  
function DirLineCounter$dir $result = array('lines_html' => false'files_count' => false'lines_count' => false ), $complete_table true )
  {

      
$file_read = array( 'php''html''js''css' );
      
$dir_ignore = array();
      
      
$scan_result scandir$dir );
      
      foreach ( 
$scan_result as $key => $value ) {
        
          if ( !
in_array$value, array( '.''..' ) ) ) {
            
              if ( 
is_dir$dir DIRECTORY_SEPARATOR $value ) ) {
                
                  if ( 
in_array$value$dir_ignore ) ) {
                    continue;
                  }
                
                  
$result DirLineCounter$dir DIRECTORY_SEPARATOR $value$resultfalse );
                  
              }
              else {
                
              
$type explode'.'$value ); 
              
$type array_reverse$type );
              if( !
in_array$type[0], $file_read ) ) {
                continue;
              }
              
              
$lines 0;
              
$handle fopen$dir DIRECTORY_SEPARATOR $value'r' );

              while ( !
feof$handle ) ) {

                  if ( 
is_bool$handle ) ) {
                      break;
                  }

                  
$line fgets$handle );
                  
$lines++;
              }

              
fclose$handle );

              
$result['lines_html'][] = '<tr><td>' $dir '</td><td>' $value '</td><td>' $lines '</td></tr>'
              
$result['lines_count'] = $result['lines_count'] + $lines;
              
$result['files_count'] = $result['files_count'] + 1;
                             
              }
          }
      }
      
      if ( 
$complete_table ) {
        
        
$lines_html implode(''$result['lines_html']) . '<tr><td></td><td style="border: 1px solid #222">Files Total: ' $result['files_count'] . '</td><td style="border: 1px solid #222">Lines Total: ' $result['lines_count'] . '</td></tr>';
        return 
'<table><tr><td style="width: 60%; background-color:#ddd;">Dir</td><td style="width: 30%; background-color:#ddd;">File</td><td style="width: 10%; background-color:#ddd;">Lines</td></tr>' $lines_html '</table>';
        
      }
      else {
        return 
$result;
      }
      
  }

  echo 
DirLineCounter'.' );

?>

[#4] eep2004 at ukr dot net [2014-10-07 09:28:18]

Fastest way to get a list of files without dots.
<?php
$files = array_slice(scandir('/path/to/directory/'), 2);

[#5] gambit_642 AT hotmailDOTcom [2014-01-22 02:04:06]

Needed something that could return the contents of single or multiple directories, recursively or non-recursively,
for all files or specified file extensions that would be
accessible easily from any scope or script.

And I wanted to allow overloading cause sometimes I'm too lazy to pass all params.
<?php
class scanDir {
    static private 
$directories$files$ext_filter$recursive;

// ----------------------------------------------------------------------------------------------
    // scan(dirpath::string|array, extensions::string|array, recursive::true|false)
    
static public function scan(){
        
// Initialize defaults
        
self::$recursive false;
        
self::$directories = array();
        
self::$files = array();
        
self::$ext_filter false;

        
// Check we have minimum parameters
        
if(!$args func_get_args()){
            die(
"Must provide a path string or array of path strings");
        }
        if(
gettype($args[0]) != "string" && gettype($args[0]) != "array"){
            die(
"Must provide a path string or array of path strings");
        }

        
// Check if recursive scan | default action: no sub-directories
        
if(isset($args[2]) && $args[2] == true){self::$recursive true;}

        
// Was a filter on file extensions included? | default action: return all file types
        
if(isset($args[1])){
            if(
gettype($args[1]) == "array"){self::$ext_filter array_map('strtolower'$args[1]);}
            else
            if(
gettype($args[1]) == "string"){self::$ext_filter[] = strtolower($args[1]);}
        }

        
// Grab path(s)
        
self::verifyPaths($args[0]);
        return 
self::$files;
    }

    static private function 
verifyPaths($paths){
        
$path_errors = array();
        if(
gettype($paths) == "string"){$paths = array($paths);}

        foreach(
$paths as $path){
            if(
is_dir($path)){
                
self::$directories[] = $path;
                
$dirContents self::find_contents($path);
            } else {
                
$path_errors[] = $path;
            }
        }

        if(
$path_errors){echo "The following directories do not exists<br />";die(var_dump($path_errors));}
    }

    
// This is how we scan directories
    
static private function find_contents($dir){
        
$result = array();
        
$root scandir($dir);
        foreach(
$root as $value){
            if(
$value === '.' || $value === '..') {continue;}
            if(
is_file($dir.DIRECTORY_SEPARATOR.$value)){
                if(!
self::$ext_filter || in_array(strtolower(pathinfo($dir.DIRECTORY_SEPARATOR.$valuePATHINFO_EXTENSION)), self::$ext_filter)){
                    
self::$files[] = $result[] = $dir.DIRECTORY_SEPARATOR.$value;
                }
                continue;
            }
            if(
self::$recursive){
                foreach(
self::find_contents($dir.DIRECTORY_SEPARATOR.$value) as $value) {
                    
self::$files[] = $result[] = $value;
                }
            }
        }
        
// Return required for recursive search
        
return $result;
    }
}
?>


Usage:
scanDir::scan(path(s):string|array, [file_extensions:string|array], [subfolders?:true|false]);
<?php
//Scan a single directory for all files, no sub-directories
$files scanDir::scan('D:\Websites\temp');

//Scan multiple directories for all files, no sub-dirs
$dirs = array(
    
'D:\folder';
    
'D:\folder2';
    
'C:\Other';
);
$files scanDir::scan($dirs);

// Scan multiple directories for files with provided file extension,
// no sub-dirs
$files scanDir::scan($dirs"jpg");
//or with an array of extensions
$file_ext = array(
    
"jpg",
    
"bmp",
    
"png"
);
$files scanDir::scan($dirs$file_ext);

// Scan multiple directories for files with any extension,
// include files in recursive sub-folders
$files scanDir::scan($dirsfalsetrue);

// Multiple dirs, with specified extensions, include sub-dir files
$files scanDir::scan($dirs$file_exttrue);
?>

[#6] Patrick [2014-01-12 21:10:05]

Here is my recursive function, placing directories into new array keys and its contents within.


function find_files($dir, &$dir_array)
{
    // Create array of current directory
    $files = scandir($dir);
    
    if(is_array($files))
    {
        foreach($files as $val)
        {
            // Skip home and previous listings
            if($val == '.' || $val == '..')
                continue;
            
            // If directory then dive deeper, else add file to directory key
            if(is_dir($dir.'/'.$val))
            {
                // Add value to current array, dir or file
                $dir_array[$dir][] = $val;
                
                find_files($dir.'/'.$val, $dir_array);
            }
            else
            {
                $dir_array[$dir][] = $val;
            }
        }
    }
    ksort($dir_array);
}

// Example
$folder_list = array();
find_files('/path', $folder_list)

var_dump($folder_list);

array(3) {
  ["directory_01"]=>
  array(4) {
    [0]=>
    string(12) "directory_02"
    [1]=>
    string(12) "directory_03"
    [2]=>
    string(11) "file_01.txt"
    [3]=>
    string(11) "file_02.txt"
  }
  ["directory_01/directory_02"]=>
  array(2) {
    [0]=>
    string(11) "file_03.txt"
    [1]=>
    string(11) "file_04.txt"
  }
  ["directory_01/directory_03"]=>
  array(2) {
    [0]=>
    string(11) "file_05.txt"
    [1]=>
    string(11) "file_06.txt"
  }
}

[#7] donovan dot pp at gmail dot com [2013-12-16 03:42:26]

Non-recursive way (red: FASTER & less memory consumption) to list all directory content :

<?php
function list_directory($dir) {
   
$file_list = array();
   
$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}";
                   
$report = array();
                   if (
is_file($current_file)) {
                       
$file_list[] = "{$current_dir}/{$file}";
                   } elseif (
is_dir($current_file)) {
                       
$stack[] = $current_file;
                       
$file_list[] = "{$current_dir}/{$file}/";
                   }
               }
           }
       }
   }

   return 
$file_list;
}

// usage :
//print_r(list_directory('C:/'));
//print_r(list_directory('C:/Users'));
print_r(list_directory('/var/www'));

?>

[#8] arfon at cradur dot com [2013-11-29 12:35:48]

Care needed going from PHP 5.3 to 5.4, as the constant SCANDIR_SORT_DESCENDING is only defined from 5.4.

I had previously been using literal, i.e. scandir($targetDir,2) in 5.3, but this did not give desired result in 5.4 (Ascending is default). However when I used SCANDIR_SORT_DESCENDING which is not defined in 5.3,  on my web host (still on 5.3) I got error - second argument assumed to be a string.

My solution (very primitive):

      $sort_desc = defined('SCANDIR_SORT_DESCENDING') ? 
                    SCANDIR_SORT_DESCENDING : 2;
      $infiles = scandir($targetDir, $sort_desc);

[#9] faruk at pamukbilisim dot com [2013-09-18 12:23:40]

<?php

    
// Directory Name
    
$dir "messages";
    
    
// Directory Control
    
if ( !is_dir$dir ) ) { die( "File <b>\" {$dir} \"</b> Not Found" ); }
    
    
// Optional
    
chmod$dir"0777" );
    
    
// Print
    
print_rscandir$dir "/" ) );
    
?>

[#10] hex at mail dot nnov dot ru [2013-09-07 19:38:35]

// Extreme minimal version recursive scan:
function rscandir($dir){
  $dirs = array_fill_keys( array_diff( scandir( $dir ), array( '.', '..' ) ), array());
  foreach( $dirs as $d => $v )
    if( is_dir($dir."/".$d) )
      $dirs[$d] = rscandir($dir."/".$d);
  return $dirs;
}

[#11] holdoffhunger at gmail dot com [2013-05-24 00:18:46]

If you would like to use scandir on the root directory of your server, you would imagine the command to be either scandir("") or scandir("/"), but neither work.  However, scandir(".") works perfectly.  Use scandir("/") and scandir("..") to poke around the Linuxy areas of your webhost.  At least, these are the observations I've made with my own webhost when it comes to root directory scandir.

[#12] mirthenemrys at gmail dot com [2013-05-21 19:25:34]

This method would leave the file system vulnerable using ../ for the ?dir= A person could navigate any readable file system simply by adding ../ enough times to get back to the root of the drive.

On a proper secure system this might not matter, however for less secure file systems where the web user(apache user) can at least read most files, or on multi-user web servers this could lead to potential security risks.

Adding a check to see if ../ is in the  $_GET["dir"] is one way to prevent this.

[#13] era_esteban at hotmail dot com [2013-05-10 15:58:52]

# Hacer hash  de estructura de directorio

$print_dir = "SOME DIR TO EXPLORE";

$parentDir=array();
myScandir($parentDir,$print_dir);
print_r ($parentDir);

function myScandir(&$parentDir,$actual_dir){
        $scanDir = scandir($actual_dir);
        for ($i=0;$i<count($scanDir);$i++){
                if ($scanDir[$i] == '.svn' || $scanDir[$i] == '.' || $scanDir[$i] == '..' ) {
                        continue;
                }
                if (is_file($actual_dir.'/'.$scanDir[$i])){
                        $file = $scanDir[$i];
                        array_push($parentDir,$file);
                } elseif (is_dir($actual_dir.'/'.$scanDir[$i])){
                        $dir =  $scanDir[$i];
                        $parentDir[$dir]=array();
                        myScandir( $parentDir[$dir] , "$actual_dir/$dir" );
                }
        }
        return true;
}

[#14] mmda dot nl at gmail dot com [2012-11-08 12:43:16]

Here is my 2 cents. I wanted to create an array of my directory structure recursively. I wanted to easely access data in a certain directory using foreach. I came up with the following:

<?php
function dirToArray($dir) {
   
   
$result = array();

   
$cdir scandir($dir);
   foreach (
$cdir as $key => $value)
   {
      if (!
in_array($value,array(".","..")))
      {
         if (
is_dir($dir DIRECTORY_SEPARATOR $value))
         {
            
$result[$value] = dirToArray($dir DIRECTORY_SEPARATOR $value);
         }
         else
         {
            
$result[] = $value;
         } 
      }
   }
   
   return 
$result;
}
?>


Output
Array
(
   [subdir1] => Array
   (
      [0] => file1.txt
      [subsubdir] => Array
      (
         [0] => file2.txt
         [1] => file3.txt
      )
   )
   [subdir2] => Array
   (
[0] => file4.txt
   }
)

[#15] carneiro at isharelife dot com dot br [2012-06-22 18:47:19]

<?php

    
function directoryToArray($directory$recursive true$listDirs false$listFiles true$exclude '') {
        
$arrayItems = array();
        
$skipByExclude false;
        
$handle opendir($directory);
        if (
$handle) {
            while (
false !== ($file readdir($handle))) {
            
preg_match("/(^(([\.]){1,2})$|(\.(svn|git|md))|(Thumbs\.db|\.DS_STORE))$/iu"$file$skip);
            if(
$exclude){
                
preg_match($exclude$file$skipByExclude);
            }
            if (!
$skip && !$skipByExclude) {
                if (
is_dir($directoryDIRECTORY_SEPARATOR $file)) {
                    if(
$recursive) {
                        
$arrayItems array_merge($arrayItemsdirectoryToArray($directoryDIRECTORY_SEPARATOR $file$recursive$listDirs$listFiles$exclude));
                    }
                    if(
$listDirs){
                        
$file $directory DIRECTORY_SEPARATOR $file;
                        
$arrayItems[] = $file;
                    }
                } else {
                    if(
$listFiles){
                        
$file $directory DIRECTORY_SEPARATOR $file;
                        
$arrayItems[] = $file;
                    }
                }
            }
        }
        
closedir($handle);
        }
        return 
$arrayItems;
    }
?>

[#16] 2bbasic at gmail dot com [2012-06-21 11:35:47]

<?php
//-- Directory Navigation with SCANDIR
//-- 
//-- optional placemenet
$exclude_list = array(".""..""example.txt");
if (isset(
$_GET["dir"])) {
  
$dir_path $_SERVER["DOCUMENT_ROOT"]."/".$_GET["dir"];
}
else {
  
$dir_path $_SERVER["DOCUMENT_ROOT"]."/";
}
//-- until here
function dir_nav() {
  global 
$exclude_list$dir_path;
  
$directories array_diff(scandir($dir_path), $exclude_list);
  echo 
"<ul style='list-style:none;padding:0'>";
  foreach(
$directories as $entry) {
    if(
is_dir($dir_path.$entry)) {
      echo 
"<li style='margin-left:1em;'>[`] <a href='?dir=".$_GET["dir"].$entry."/"."'>".$entry."</a></li>";
    }
  }
  echo 
"</ul>";
  
//-- separator
  
echo "<ul style='list-style:none;padding:0'>";
  foreach(
$directories as $entry) {
    if(
is_file($dir_path.$entry)) {
      echo 
"<li style='margin-left:1em;'>[ ] <a href='?file=".$_GET["dir"].$entry."'>".$entry."</a></li>";
    }
  }
  echo 
"</ul>";
}
dir_nav();
//-- optional placement
if (isset($_GET["file"])) {
  echo 
"<div style='margin:1em;border:1px solid Silver;'>";
  
highlight_file($dir_path.$_GET['file']);
  echo 
"</div>";
}
//-- until here
//--
//-- Because I love php.net
?>

[#17] fazle dot elahee at gmail dot com [2012-04-09 18:52:42]



function scanFileNameRecursivly($path = '', &$name = array() )
{
  $path = $path == ''? dirname(__FILE__) : $path;
  $lists = @scandir($path);
  
  if(!empty($lists))
  {
      foreach($lists as $f)
      { 

  if(is_dir($path.DIRECTORY_SEPARATOR.$f) && $f != ".." && $f != ".")
  {
      scanFileNameRecursivly($path.DIRECTORY_SEPARATOR.$f, &$name); 
  }
  else
  {
      $name[] = $path.DIRECTORY_SEPARATOR.$f;
  }
      }
  }
  return $name;
}

$path = "/var/www/SimplejQueryDropdowns";
$file_names = scanFileNameRecursivly($path);

echo "<pre>";
var_dump($file_names);
echo "</pre>";

[#18] dwieeb at gmail dot com [2012-01-22 08:06:56]

Easy way to get rid of the dots that scandir() picks up in Linux environments:

<?php
$directory 
'/path/to/my/directory';
$scanned_directory array_diff(scandir($directory), array('..''.'));
?>

[#19] kodlee at kodleeshare dot net [2012-01-08 15:51:16]

I needed to find a way to get the full path of all files in the directory and all subdirectories of a directory.
Here's my solution: Recursive functions!

<?php
function find_all_files($dir)
{
    
$root scandir($dir);
    foreach(
$root as $value)
    {
        if(
$value === '.' || $value === '..') {continue;}
        if(
is_file("$dir/$value")) {$result[]="$dir/$value";continue;}
        foreach(
find_all_files("$dir/$value") as $value)
        {
            
$result[]=$value;
        }
    }
    return 
$result;
}
?>

[#20] Gerjoo at gmail dot com [2011-05-26 11:41:53]

If you wish to sort by folders first then files, you could use something like this:

<?php
function scandirSorted($path) {
    
$sortedData = array();
    foreach(
scandir($path) as $file) {
        if(
is_file($path $file)) {
            
array_push($sortedData$file);
        } else {
            
array_unshift($sortedData$file);
        }
    }
    return 
$sortedData;
}
?>


NB.: This approach *might* be suboptimal for high performance situations.

- Gerard

[#21] robin leffmann [2010-11-25 12:33:37]

Note that scandir() will enforce alphanumerical sorting on the array it returns. If you wish to reduce CPU overhead by avoiding the sorting, or if you wish to obtain "natural filesystem order" - that is, the order in which the files are found while traversing the filesystem (usually the order in which they were written to the disk) - you need to go back to the PHP4 equivalent of opendir() + readdir().

[#22] boen dot robot at gmail dot com [2010-02-20 10:10:54]

If you have a folder with many files and/or subfolders, doing a recursive scandir will likely either slow down your application, or cause a high rise in RAM consumption due to the large size of the generated array.

To help with this, as well as to make processing of files in a folder easier, I wrote a function that reads a folder and its subfolders recursively, and calls a function upon each match.

<?php

function dir_walk($callback$dir$types null$recursive false$baseDir '') {
    if (
$dh opendir($dir)) {
        while ((
$file readdir($dh)) !== false) {
            if (
$file === '.' || $file === '..') {
                continue;
            }
            if (
is_file($dir $file)) {
                if (
is_array($types)) {
                    if (!
in_array(strtolower(pathinfo($dir $filePATHINFO_EXTENSION)), $typestrue)) {
                        continue;
                    }
                }
                
$callback($baseDir $file);
            }elseif(
$recursive && is_dir($dir $file)) {
                
dir_walk($callback$dir $file DIRECTORY_SEPARATOR$types$recursive$baseDir $file DIRECTORY_SEPARATOR);
            }
        }
        
closedir($dh);
    }
}
?>


Of course, because it is recursive, a folder with many levels of folders could potentially consume lots of memory, but then again, so can every other recursive scandir implementation here.

BTW, there's also the RecursiveDirectoryIterator SPL class:
http://bg.php.net/manual/en/class.recursivedirectoryiterator.php
which, even if using the same approach, will most likely be faster and hold down deeper levels (because it works on the C level), but this one will always work, regardless of settings... even on PHP4.

Point is, avoid recursive scandir implementations.

[#23] franzemmanuel at gmail dot com [2010-02-10 13:44:12]

Scandir does not work properly with non-english caracters (like french accents for example : ???????...) in the files name.
As PHP does not support unicode operations until PHP 6, this is not a bug.

[#24] moik78 at gmail dot com [2010-01-28 05:43:11]

This is a function to count the number of files of a directory

<?php
function countFiles($dir){
    
$files = array();
    
$directory opendir($dir); 
    while(
$item readdir($directory)){
    
// We filter the elements that we don't want to appear ".", ".." and ".svn" 
         
if(($item != ".") && ($item != "..") && ($item != ".svn") ){ 
              
$files[] = $item
         } 
    }
    
$numFiles count($files);
    return 
$numFiles;
}
?>

[#25] phpnet at novaclic dot com [2010-01-11 02:36:07]

Was looking for a simple way to search for a file/directory using a mask. Here is such a function.

By default, this function will keep in memory the scandir() result, to avoid scaning multiple time for the same directory.

Requires at least PHP5.

<?php
function sdir$path='.'$mask='*'$nocache=){
    static 
$dir = array(); // cache result in memory
    
if ( !isset($dir[$path]) || $nocache) {
        
$dir[$path] = scandir($path);
    } 
    foreach (
$dir[$path] as $i=>$entry) {
        if (
$entry!='.' && $entry!='..' && fnmatch($mask$entry) ) {
            
$sdir[] = $entry;
        }
    }
    return (
$sdir);
}
?>

[#26] magicmind at netcabo dot pt [2009-06-09 05:20:00]

Hello all,

I just added a extension filter to the getDirectoryTree function, so it can filter an extension for files in the folders/subfolders:

<?php
function getDirectoryTree$outerDir $x){ 
    
$dirs array_diffscandir$outerDir ), Array( "."".." ) ); 
    
$dir_array = Array(); 
    foreach( 
$dirs as $d ){ 
        if( 
is_dir($outerDir."/".$d)  ){
            
$dir_array$d ] = getDirectoryTree$outerDir."/".$d $x); 
        }else{
         if ((
$x)?ereg($x.'$',$d):1
            
$dir_array$d ] = $d
            }
    } 
    return 
$dir_array


$dirlist getDirectoryTree('filmes','flv');
?>

[#27] phpdotnet at lavavortex dot com [2009-05-01 05:05:01]

How a ninja may retrieve a list of files, files filtered by extension, or directories:

<?php
//NNNIIIinnnjaaa::
//array of files without directories... optionally filtered by extension
function file_list($d,$x){
       foreach(
array_diff(scandir($d),array('.','..')) as $f)if(is_file($d.'/'.$f)&&(($x)?ereg($x.'$',$f):1))$l[]=$f;
       return 
$l;
}

//NNNIIIinnnjaaa::
//array of directories
function dir_list($d){
       foreach(
array_diff(scandir($d),array('.','..')) as $f)if(is_dir($d.'/'.$f))$l[]=$f;
       return 
$l;
}





//(note: one slash (/) below and you enable all your test functions, guess where ;-))





?>

[#28] kyperkins at gmail dot com [2009-02-04 15:11:46]

Here's a simple little scandir() function that can pick a random photo (jpg only so far) and dislpay it. This also goes through an exclusion list and doesn't store anything you don't want to display. Use as you wish

<?php
        $dir
=scandir("photos");
        
$exclude=array("photos/.","photos/..","photos/ex");
        
$photos=array();
        for (
$x=0$x<count($dir); $x++){
            
$dir[$x]="photos/".$dir[$x];
            if (
is_dir($dir[$x]) && !in_array($dir[$x], $exclude)){
                
$thisfolder=scandir($dir[$x]);
                for (
$f=0$f<count($thisfolder); $f++)
                if (
strpos(strtolower($thisfolder[$f]), ".jpg"))
                    
$photos[]=$dir[$x]."/".$thisfolder[$f];
            }
        }
        
$rand=rand(0count($photos));
        echo 
"<div style='text-align: center;'>";
        echo 
"<img src='".$photos[$rand]."' alt='' style='width: 80%'/>";
        echo 
"</div>";
        
?>

[#29] Dustin [2009-01-05 15:37:51]

If I'm remembering my CS classes right... this would be the 'bare bones' recursive method to extract directories and files... 

<?php
function getDirectoryTree$outerDir ){
    
$dirs array_diffscandir$outerDir ), Array( "."".." ) );
    
$dir_array = Array();
    foreach( 
$dirs as $d ){
        if( 
is_dir($outerDir."/".$d) ) $dir_array$d ] = getDirectoryTree$outerDir."/".$d );
        else 
$dir_array$d ] = $d;
    }
    return 
$dir_array;
}
?>

[#30] admin at utahfishinginfo dot com [2008-12-19 15:47:24]

Here is a function that parses your website's directory tree, similar to the scanDirectories function provided by fatpratmatt.  However, this allows you to filter out all files except for those with specific extensions, in addition to allowing you to ignore entire directories, and also has a list of specific files to ignore.  One last addition is that it allows you to use a regular expression to ignore another set of files.

I use this to walk the directory structure of my website, and to generate a sitemap.xml for Google sitemaps to index my site.  This allows me to skip dev, data, library, etc. folders, and files that are not front end files.

The way it's written means you don't need to worry about excluding specific files at all unless they have the extension you are looking for (i.e. html or php files).

Enjoy.

<?php
  
function get_files($root_dir$all_data=array()) 
  {
    
// only include files with these extensions
    
$allow_extensions = array("php""html");
    
// make any specific files you wish to be excluded
    
$ignore_files = array("gdform.php","fishheader.php","fishfooter.php",
      
"sitelinks.php","google204accd1c3ac0501.html","sitemapxml.php",
      
"rotate.php""fishstockingreport2.php""repcentral.php""repne.php",
      
"repnorth.php","reppowell.php","repse.php","repsouth.php","repse.php",
      
"stockreplib.php","iestyles.php");
    
$ignore_regex '/^_/';
    
// skip these directories
    
$ignore_dirs = array(".""..""images""dev""lib""data""osh""fiq""google",
      
"stats""_db_backups""maps""php_uploads""test");

    
// run through content of root directory
    
$dir_content scandir($root_dir); 
    foreach(
$dir_content as $key => $content)
    {
      
$path $root_dir.'/'.$content;
      if(
is_file($path) && is_readable($path)) 
      {
        
// skip ignored files
        
if(!in_array($content$ignore_files)) 
        {
          if (
preg_match($ignore_regex,$content) == 0)
          {
            
$content_chunks explode(".",$content);
            
$ext $content_chunks[count($content_chunks) - 1];
            
// only include files with desired extensions
            
if (in_array($ext$allow_extensions))
            {
                
// save file name with path
                
$all_data[] = $path;    
            }
          }
        }
      }
      
// if content is a directory and readable, add path and name
      
elseif(is_dir($path) && is_readable($path)) 
      {
        
// skip any ignored dirs
        
if(!in_array($content$ignore_dirs))
        {
          
// recursive callback to open new directory
          
$all_data get_files($path$all_data);
        }
      }
    } 
// end foreach
    
return $all_data;
  } 
// end get_files()

?>

[#31] dsiembab at fullchannel dot net [2008-12-08 23:29:58]

Back in the saddle of scandir I wrote this function for a function that I needed to seperate directories from files. Since I am still learning from my last example way below I would figure I would add it so it can be criticized.
<?php
function dirlist($dir$bool "dirs"){
   
$truedir $dir;
   
$dir scandir($dir);
   if(
$bool == "files"){ // dynamic function based on second pram
      
$direct 'is_dir'
   }elseif(
$bool == "dirs"){
      
$direct 'is_file';
   }
   foreach(
$dir as $k => $v){
      if((
$direct($truedir.$dir[$k])) || $dir[$k] == '.' || $dir[$k] == '..' ){
         unset(
$dir[$k]);
      }
   }
   
$dir array_values($dir);
   return 
$dir;
}
?>

<?php
print_r
(dirlist("../"));  //confirm array of subdirectories

print_r(dirlist("../""files"// confirm list on files in the directory 
?>

[#32] webmaster at asylum-et dot com [2008-07-23 00:50:27]

<?php

function rscandir($base='', &$data=array()) {
  
  
$array array_diff(scandir($base), array('.''..')); # remove ' and .. from the array */
   
  
foreach($array as $value) : 
  
    
if (is_dir($base.$value)) : 
      
$data[] = $base.$value.'/'
      
$data rscandir($base.$value.'/'$data); 
      
    
elseif (is_file($base.$value)) : 
      
$data[] = $base.$value
      
    
endif;
    
  endforeach;
  
  return 
$data// return the $data array
  
}

echo 
'<pre>'var_export(rscandir(dirname(__FILE__).'/')); echo '</pre>';

?>

[#33] asamir at asamir dot net [2008-03-05 04:21:39]

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($contentstrrpos($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);
?>

[#34] SlowWalkere at gmail dot com [2008-02-15 16:22:58]

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...

[#35] fatpratmatt dot at dot gmail dot com [2007-12-27 04:28:16]

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
)

[#36] cHH [2007-11-05 09:46:26]

Since scandir() returns and array, here is a more concise method of dealing with the '.' and '..' problem when listing directories:

<?php
$target 
'/';
$weeds = array('.''..');
$directories array_diff(scandir($target), $weeds);
    
foreach(
$directories as $value)
{
   if(
is_dir($target.$value))
   {
      echo 
$value.'<br />';
   }
}
?>

[#37] deryckchan at gmail dot com [2007-08-30 19:44:05]

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().

[#38] dsiembab at fullchannel dot net [2007-06-28 12:51:25]

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);


$dir '.';
$dh  opendir($dir);
while (
false !== ($filename readdir($dh))) {
    
$files[] =$filename;
}
$t=array_slice($files,2);
$f=array_search('index.php',$t);

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.

[#39] aryel at redtwilight dot com dot br [2007-02-07 11:07:41]

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;
}
?>

[#40] beingmrkenny at gmail dot com [2006-08-13 11:41:32]

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.

[#41] www.mdsjack.bo.it [2006-04-07 11:54:34]

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;
}



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);
}

?>

[#42] Yassin Ezbakhe <yassin88 at gmail dot com> [2005-08-31 16:18:47]

<?php


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;
}
?>

[#43] trevi55 at gmail dot com [2005-07-08 05:38:00]

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.

<?php
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($filesSORT_STRING);
    else
        
sort($filesSORT_STRING);
    
    return 
$files;
}
?>

[#44] progrium+php at gmail dot com [2005-06-30 16:54:48]

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($filename01)) {
               
$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
)

[#45] Pawel Dlugosz [2005-05-11 11:18:28]

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 :)

[#46] wwwebdesigner at web doott de [2005-04-12 12:20:44]

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
)

[#47] brodseba at brodseba dot com [2005-03-24 20:53:32]

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!

<?php
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($currentfilestrrpos($currentfile'/')) . "</a><br>";
          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($currentfilestrrpos($currentfile'/')) . "</a><br>";
        echo 
$last_dir;
      }
    }
  }
}
?>

[#48] csaba at alum dot mit dot edu [2005-03-04 15:19:09]

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-&& ($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');
?>


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

[#49] csaba at alum dot mit dot edu [2005-03-04 04:52:55]

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

[#50] virtual at NOSPAM dot lapinbleu dot ch [2005-02-09 05:58:11]

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]."<br>"//Complete path of the file with key 0 (dir + filename)

echo $yourvar["directory"][0]."<br>"//Directory of the file with key 0

echo $yourvar["filename"][0]."<br>"//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.

[#51] Stan P. van de Burgt [2004-10-26 09:05:57]

scandir() with regexp matching on file name and sorting options based on stat().

<?php
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

[#52] aidan at php dot net [2004-05-20 19:14:21]

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

上一篇: 下一篇: