Как игнорировать каталоги с помощью RecursiveIteratorIterator?

Я попытался несколько методов игнорировать некоторые каталоги, используя RecursiveIteratorIterator в файловой системе.

Для примера скажем, я хочу игнорировать следующий каталог: /cache .

Мой Iterator выглядит так:

 //$dirname is root $directory = new RecursiveDirectoryIterator($dirname); $mega = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST); foreach ($mega as $fileinfo) { echo $fileinfo; } 

Я мог игнорировать некоторые расширения файлов с помощью pathinfo например, это работает:

 $filetypes = array("jpg", "png"); $filetype = pathinfo($fileinfo, PATHINFO_EXTENSION); foreach ($mega as $fileinfo) { if (!in_array(strtolower($filetype), $filetypes)) { echo $fileinfo; } } 

Когда я пытаюсь использовать PATHINFO_DIRNAME (с соответствующими каталогами в массиве), это не работает, ошибок нет, он просто не игнорирует каталоги.

Я также экспериментировал с использованием FilterIterator безрезультатно, и теперь я думаю, что я должен использовать RegexIterator .

Каким будет самый простой и эффективный способ игнорировать каталоги с помощью RecursiveIteratorIterator ?


Эксперименты, которые не сработали. Использование 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 } 

Использование FilterIterator (не знаю, как это работает)

 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 приводит к Error: An instance of RecursiveIterator or IteratorAggregate creating it is required

Solutions Collecting From Web of "Как игнорировать каталоги с помощью RecursiveIteratorIterator?"

Ваш DirFilter хочет расширить RecursiveFilterIterator , поскольку он используется с рекурсивным итератором. Не делая этого, является причиной вашей ошибки.

 class DirFilter extends RecursiveFilterIterator { // … } 

Следующий шаг – выяснить, как правильно использовать accept() . Он должен возвращать true или false значение, которое определяет, должен ли текущий элемент быть включен ( true ) или исключен ( false ) из итерации. Возвращение имени файла из accept() не является тем, что вы хотите делать.

 class DirFilter extends RecursiveFilterIterator { public function accept() { $excludes = array("cache", "cache2"); return !($this->isDir() && in_array($this->getFilename(), $excludes)); } } 

Возможно, было бы неплохо пройти в массив исключенных каталогов. Для этого требуется немного больше кода, но он гораздо более многоразовый.

 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); } } 

Затем этот код можно использовать как:

 $directory = new RecursiveDirectoryIterator($dirname); $filtered = new DirFilter($directory, $dirignore); $mega = new RecursiveIteratorIterator($filtered, …);