How to ignore directories using RecursiveIteratorIterator?
iterator, php
Solution
Your `DirFilter` wants to extend `RecursiveFilterIterator`, since it is being used with a recursive iterator. Not doing that, is the cause of your error.
class DirFilter extends RecursiveFilterIterator
{
// …
}
The next step is figuring out how to use `accept()` properly. It is supposed to return a `true` or `false` value, which dictates whether the current item should be included (`true`) or excluded (`false`) from the iteration. Returning a file name from `accept()` is not what you want to be doing.
class DirFilter extends RecursiveFilterIterator
{
public function accept()
{
$excludes = array("cache", "cache2");
return !($this->isDir() && in_array($this->getFilename(), $excludes));
}
}
It might be nice to be able to pass in the array of excluded directories. This requires a little more code but is much more reusable.
class DirFilter extends RecursiveFilterIterator
{
protected $exclude;
public function __construct($iterator, array $exclude)
{
parent::__construct($iterator);
$this->exclude = $exclude;
}
public function accept()
{
return !($this->isDir() && in_array($this->getFilename(), $this->exclude));
}
public function getChildren()
{
return new DirFilter($this->getInnerIterator()->getChildren(), $this->exclude);
}
}
This code could then be used like:
$directory = new RecursiveDirectoryIterator($dirname);
$filtered = new DirFilter($directory, $dirignore);
$mega = new RecursiveIteratorIterator($filtered, …);
Problem
I have tried several methods to ignore certain directories using `RecursiveIteratorIterator` on a file system. For the sake of an example say I want to ignore the following directory: `/cache`. My `Iterator` looks like this: ``` //$dirname is root $directory = new RecursiveDirectoryIterator($dirname); $mega = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST); foreach ($mega as $fileinfo) { echo $fileinfo; } ``` I have been able to ignore certain file extensions using `pathinfo` for example this works: ``` $filetypes = array("jpg", "png"); $filetype = pathinfo($fileinfo, PATHINFO_EXTENSION); foreach ($mega as $fileinfo) { if (!in_array(strtolower($filetype), $filetypes)) { echo $fileinfo; } } ``` When I try it using `PATHINFO_DIRNAME` (with the appropriate directory paths in the array) it does not work, there are no errors, it just does not ignore the directories. I have also experimented with using `FilterIterator` to no avail, and now I'm thinking maybe I should use `RegexIterator`. What would be the simplest and most efficient way to ignore directories using `RecursiveIteratorIterator` ? Experiments that didn't work. Using `PATHINFO_DIRNAME` ``` $dirignore = array("cache", "cache2"); $directory = new RecursiveDirectoryIterator($dirname); $mega = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST); $dirtype = pathinfo($fileinfo, PATHINFO_DIRNAME); if (!in_array($dirtype), $dirignore)) { echo $fileinfo; //no worky still echo directories } ``` Using `FilterIterator` (not sure how this works) ``` class DirFilter extends FilterIterator { public function accept() { //return parent::current() != "..\cache\"; $file = $this->getInnerIterator()->current(); if ($file != "..\cache") return $file->getFilename(); //also tried with same error as below //return !preg_match('/\cache', $file->getFilename()); } } $directory= new RecursiveDirectoryIterator($dirname); $directory = new DirFilter($directory); $mega = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST); // loop ``` Tis results in `Error: An instance of RecursiveIterator or IteratorAggregate creating it is required`