Since I continue to run into implementations across the net that are unintentionally running into this trap — beware:
RecursiveDirectoryIterator recurses without limitations into the full filesystem tree.
Do NOT do the following, unless you intentionally want to infinitely recurse without limitations:
<?php
$directory = new \RecursiveDirectoryIterator($path);
$iterator = new \RecursiveIteratorIterator($directory);
$files = array();
foreach ($iterator as $info) {
if (...custom conditions...) {
$files[] = $info->getPathname();
}
}
?>
1. RecursiveDirectoryIterator is just a RecursiveIterator that recurses into its children, until no more children are found.
2. The instantiation of RecursiveIteratorIterator causes RecursiveDirectoryIterator to *immediately* recurse infinitely into the entire filesystem tree (starting from the given base path).
3. Unnecessary filesystem recursion is slow. In 90% of all cases, this is not what you want.
Remember this simple rule of thumb:
→ A RecursiveDirectoryIterator must be FILTERED or you have a solid reason for why it shouldn't.
On PHP <5.4, implement the following - your custom conditions move into a proper filter:
<?php
$directory = new \RecursiveDirectoryIterator($path, \FilesystemIterator::FOLLOW_SYMLINKS);
$filter = new MyRecursiveFilterIterator($directory);
$iterator = new \RecursiveIteratorIterator($filter);
$files = array();
foreach ($iterator as $info) {
$files[] = $info->getPathname();
}
class MyRecursiveFilterIterator extends \RecursiveFilterIterator {
public function accept() {
$filename = $this->current()->getFilename();
if ($name[0] === '.') {
return FALSE;
}
if ($this->isDir()) {
return $name === 'wanted_dirname';
}
else {
return strpos($name, 'wanted_filename') === 0;
}
}
}
?>
On PHP 5.4+, PHP core addressed the slightly cumbersome issue of having to create an entirely new class and you can leverage the new RecursiveCallbackFilterIterator instead:
<?php
$directory = new \RecursiveDirectoryIterator($path, \FilesystemIterator::FOLLOW_SYMLINKS);
$filter = new \RecursiveCallbackFilterIterator($directory, function ($current, $key, $iterator) {
if ($current->getFilename()[0] === '.') {
return FALSE;
}
if ($current->isDir()) {
return $current->getFilename() === 'wanted_dirname';
}
else {
return strpos($current->getFilename(), 'wanted_filename') === 0;
}
});
$iterator = new \RecursiveIteratorIterator($filter);
$files = array();
foreach ($iterator as $info) {
$files[] = $info->getPathname();
}
?>
Have fun!