scandir
Возвращает массив ( array ), содержащий имена файлов и каталогов, расположенных по пути, переданном в параметре directory .
Список параметров
По умолчанию сортировка производится в алфавитном порядке по возрастанию. Если необязательный параметр sorting_order установлен в значение SCANDIR_SORT_DESCENDING , сортировка производится в алфавитном порядке по убыванию. Если же он установлен в значение SCANDIR_SORT_NONE , то сортировка не производится.
За описанием параметра context обратитесь к разделу Потоки данного руководства.
Возвращаемые значения
Возвращает массив ( array ) имён файлов в случае успешного выполнения или false в случае возникновения ошибки. Если directory не является каталогом, возвращается false и генерируется сообщение об ошибке уровня E_WARNING .
Список изменений
Примеры
Пример #1 Простой пример использования функции scandir()
$dir = ‘/tmp’ ;
$files1 = scandir ( $dir );
$files2 = scandir ( $dir , SCANDIR_SORT_DESCENDING );
?php
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] => . )
Примечания
Для этой функции вы можете использовать URL в качестве имени файла, если была включена опция fopen wrappers. Смотрите более подробную информацию об определении имени файла в описании функции fopen() . Смотрите также список поддерживаемых обёрток URL, их возможности, замечания по использованию и список предопределённых констант в разделе Поддерживаемые протоколы и обёртки.
Смотрите также
- opendir() — Открывает дескриптор каталога
- readdir() — Получает элемент каталога по его дескриптору
- glob() — Находит файловые пути, совпадающие с шаблоном
- is_dir() — Определяет, является ли имя файла директорией
- sort() — Сортирует массив по возрастанию
User Contributed Notes 38 notes
Easy way to get rid of the dots that scandir() picks up in Linux environments:
$directory = ‘/path/to/my/directory’ ;
$scanned_directory = array_diff ( scandir ( $directory ), array( ‘..’ , ‘.’ ));
?>
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:
$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
>
)
Someone wrote that array_slice could be used to quickly remove directory entries «.» and «..». However, «-» is a valid entry that would come before those, so array_slice would remove the wrong entries.
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!
function find_all_files ( $dir )
<
$root = scandir ( $dir );
foreach( $root as $value )
<
if( $value === ‘.’ || $value === ‘..’ )
if( is_file ( » $dir / $value » )) < $result []= " $dir / $value " ;continue;>
foreach( find_all_files ( » $dir / $value » ) as $value )
<
$result []= $value ;
>
>
return $result ;
>
?>
For directory containing files like (for example) -.jpg the results of scandir are a little «weird» 😉
$dir = ‘/somedir’ ;
$files = scandir ( $dir );
print_r ( $files );
?>
Array
(
[0] => -.jpg
[1] => .
[2] => ..
[3] => foo.txt
[4] => somedir
)
Beware — sorting is in ASCII order 🙂
A simple recursive function to list all files and subdirectories in a directory:
function listAllFiles ( $dir ) $array = array_diff ( scandir ( $dir ), array( ‘.’ , ‘..’ ));
foreach ( $array as & $item ) $item = $dir . $item ;
>
unset( $item );
foreach ( $array as $item ) if ( is_dir ( $item )) $array = array_merge ( $array , listAllFiles ( $item . DIRECTORY_SEPARATOR ));
>
>
return $array ;
>
?>
Fastest way to get a list of files without dots.
$files = array_slice ( scandir ( ‘/path/to/directory/’ ), 2 );
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.
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 )
// 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» )
foreach( $paths as $path ) if( is_dir ( $path )) self :: $directories [] = $path ;
$dirContents = self :: find_contents ( $path );
> else $path_errors [] = $path ;
>
>
// This is how we scan directories
static private function find_contents ( $dir ) $result = array();
$root = scandir ( $dir );
foreach( $root as $value ) if( $value === ‘.’ || $value === ‘..’ )
if( is_file ( $dir . DIRECTORY_SEPARATOR . $value )) if(! self :: $ext_filter || in_array ( strtolower ( pathinfo ( $dir . DIRECTORY_SEPARATOR . $value , PATHINFO_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]);
//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 ( $dirs , false , true );
// Multiple dirs, with specified extensions, include sub-dir files
$files = scanDir :: scan ( $dirs , $file_ext , true );
?>
Scandir on steroids:
For when you want to filter your file list, or only want to list so many levels of subdirectories.
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:
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).