We need to get a list of specific files from a directory.
Say we need to find all *.php files in our c:\inetpub\wwwroot folder. There are a couple of options to do it in PHP: opendir(), glob(), scandir() and RecursiveDirectoryIterator class. If we need to search through subfolders then the simplest solution in my opinion is to use the RecursiveDirectoryIterator class.
function readdirRecursiveDirectory($dir, $extension) { $files = array(); if (!file_exists($dir)) return $files; $strRegexp = '/^.+\.'.$extension.'$/i'; //note the i here - case insensitive regexp $iteratorDirectory = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir)); $iteratorRegex = new \RegexIterator($iteratorDirectory, $strRegexp, \RecursiveRegexIterator::GET_MATCH); foreach ($iteratorRegex as $filepath => $fileinfo) { if ( is_file($filepath) ) { $files[] = $filepath; } } return $files; }
But there is a faster solution based on scandir() php buildin function. This recursive function is about 5% faster in my tests then the previous solution.
function readdirScandir($dir, $extension) { $files = array(); $root = @scandir($dir, SCANDIR_SORT_NONE); foreach($root as $entry) { if($entry === '.' || $entry === '..') continue; $fullpath = $dir.'/'.$entry; if(is_file($fullpath)) { if (0 === strcasecmp($extension, pathinfo($fullpath, PATHINFO_EXTENSION))) $files[] = $fullpath; continue; } foreach(readdirScandir($fullpath, $extension) as $entry) { if(0 === strcasecmp($extension, pathinfo($entry, PATHINFO_EXTENSION))) { $files[] = $entry; } } } return $files; }
My results searching for 2173 php-files through c:\inetpub\wwwroot directory with totally ~90000 files in 10927 folders.
readdirRecursiveDirectory - 42sec
readdirScandir - 39sec