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