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