Reputation: 1292
I have a recursive directory iterator to select files from within a directory. SKIP_DOTS allows me to ignore the '.' and '..' elements, but I'd like to be able to also ignore '__MACOSX' directory and another other hidden files such as '.cache.php'
$iterator = new RecursiveDirectoryIterator($directory);
$iterator->setFlags(RecursiveDirectoryIterator::SKIP_DOTS);
$all_files = new RecursiveIteratorIterator($iterator);
There are other answers here and here but just wondered if there was a cleaner way?
I was hoping there was going to be something in PHP Manual - FilesystemIterator SetFlags but it seems not.
Upvotes: 8
Views: 8174
Reputation: 1
To filter other items, you can utilize RecursiveCallbackFilterIterator
. This
is nice because with folders that hit the filter, the entire subpath is pruned.
Here is an example filtering a file and subfolder:
<?php
$f_filter = function ($o_info) {
$s_file = $o_info->getFilename();
if ($s_file == '.git') {
return false;
}
if ($s_file == 'readme.md') {
return false;
}
return true;
};
$o_dir = new RecursiveDirectoryIterator('.');
$o_filter = new RecursiveCallbackFilterIterator($o_dir, $f_filter);
$o_iter = new RecursiveIteratorIterator($o_filter);
foreach ($o_iter as $o_info) {
echo $o_info->getPathname(), "\n";
}
https://php.net/class.recursivecallbackfilteriterator
Upvotes: 1
Reputation: 1292
Thanks to @Sven and the PHP Docs:
$iterator = new RecursiveDirectoryIterator($directory);
$iterator->setFlags(RecursiveDirectoryIterator::SKIP_DOTS);
$filter = new MyRecursiveFilterIterator($iterator);
$all_files = new RecursiveIteratorIterator($filter,RecursiveIteratorIterator::SELF_FIRST);
Then extended RecursiveFilterIterator
class MyRecursiveFilterIterator extends RecursiveFilterIterator {
public static $FILTERS = array(
'__MACOSX',
);
public function accept() {
return !in_array(
$this->current()->getFilename(),
self::$FILTERS,
true
);
}
}
As per the comment In the PHP Manual
Upvotes: 11
Reputation: 70933
Add a filter layer between RecursiveIteratorIterator and RecursiveDirectoryIterator: Create a RecursiveFilterIterator and code the accept()
function that returns true if you want the element to be in the result. Put the directory iterator into the filter iterator, put the filter iterator in the RecursiveIteratorIterator. Iterate.
There is no predefined SKIP constant for such special cases as "__MACOSX" directories.
Upvotes: 1