Могу ли я заставить RecursiveDirectoryIterator пропускать нечитаемые каталоги?

foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator(".")) as $file) { echo "$file\n"; } 

Есть ли способ для этого кода не бросать UnexpectedValueException «не удалось открыть dir: Permission denied» всякий раз, когда есть недопустимый подкаталог внутри каталога, который я пытаюсь перечислить?

ОБНОВИТЬ

Преобразование foreach() в while() и явно вызов Iterator::next() завернутый в try() catch {} , не помогает. Этот код:

 $iter = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(".")); while($iter->valid()) { $file = $iter->current(); echo "$file\n"; try { $iter->next(); } catch(UnexpectedValueException $e) { } }; 

является бесконечным циклом, если есть нечитаемый подкаталог.

Очевидно, вы можете передать параметр $flags в конструктор. В документах есть только один флаг , но он делает именно то, что вы хотите: catches exceptions during getChildren() calls and simply jumps to the next element .

Измените код создания класса на

 new RecursiveIteratorIterator( new RecursiveDirectoryIterator("."), RecursiveIteratorIterator::LEAVES_ONLY, RecursiveIteratorIterator::CATCH_GET_CHILD); 

и он должен работать

Вы могли бы сделать что-то вроде этого:

 class ReadableFilter extends RecursiveFilterIterator{ public function accept(){ return $this->current()->isReadable(); } } $filteredIterator = new RecursiveIteratorIterator(new ReadableFilter(new RecursiveDirectoryIterator("."))); foreach ($filteredIterator as $file){ echo "$file\n"; } 

Возможно, позиция итератора будет действительна, даже если каталог не читается.

Вы можете проверить состояние записи в каталоге. Неверный непроверенный пример кода:

 $iter = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(".")); foreach ($iter as $dir) { if($dir->isReadable()){ //do something } }