Могу ли я заставить 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) {
}
};
бесконечный цикл, если есть нечитаемый подкаталог.
3 ответа
Видимо, вы можете пройти $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
}
}