Могу ли я заставить RecursiveDirectoryIterator пропускать нечитаемые каталоги?
foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator(".")) as $file) {
echo "$file\n";
}
Есть ли какой-либо способ для этого кода не выбрасывать UnexpectedValueException "не удалось открыть dir: Permission denied" всякий раз, когда есть недопустимый подкаталог внутри каталога, который я пытаюсь перечислить?
UPDATE
Преобразование 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) {
}
};
является бесконечным циклом, если существует нечитаемый подкаталог.
Ответы
Ответ 1
По-видимому, вы можете передать параметр $flags
в конструктор. Там только один флаг в документах, но он делает именно то, что вы хотите: catches exceptions during getChildren() calls and simply jumps to the next element
.
Измените код создания класса на
new RecursiveIteratorIterator(
new RecursiveDirectoryIterator("."),
RecursiveIteratorIterator::LEAVES_ONLY,
RecursiveIteratorIterator::CATCH_GET_CHILD);
и он должен работать
Ответ 2
Вы можете сделать что-то вроде этого:
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";
}
Ответ 3
Возможно, позиция итератора будет действительна, даже если каталог не читается.
Вы можете проверить состояние записи в каталоге. Неверный непроверенный пример кода:
$iter = new RecursiveIteratorIterator(new RecursiveDirectoryIterator("."));
foreach ($iter as $dir) {
if($dir->isReadable()){
//do something
}
}