2010-12-28 14 views
15
foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator(".")) as $file) { 
    echo "$file\n"; 
} 

¿Hay alguna manera de que este código no se emita UnexpectedValueException "no se pudo abrir dir: Permiso denegado" cuando hay un subdirectorio ilegible dentro del directorio que intento enumerar?¿Puedo hacer que RecursiveDirectoryIterator omita directorios ilegibles?

ACTUALIZACIÓN

conversión de foreach() a while() y una llamada explícita a Iterator::next() envuelto en try() catch {} no ayuda. Este código:

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

es un bucle infinito si hay un subdirectorio ilegible.

+0

envolverla en bloques intento de captura. y parece ser una mala idea crear nuevos objetos dentro de paréntesis foreach – s3v3n

+0

Para elaborar sobre el comentario de s3v3n. Parece ser una mala idea, porque lo que está sucediendo es muy difícil de determinar. Un buen código no siempre es el código más pequeño o más rápido. – DampeS8N

+0

No es difícil determinar qué sucede si sabe qué es RecursiveIteratorIterator y RecursiveDirectoryIterator y cuál es su caso de uso común. Es un código simple. –

Respuesta

19

Al parecer, usted puede pasar $flags parámetro para el constructor. Solo hay one flag in the docs, pero hace exactamente lo que desea: catches exceptions during getChildren() calls and simply jumps to the next element.

cambiar el código de creación de clases a

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

y debería funcionar

+0

Eso es exactamente lo que necesitaba. ¡Muchas gracias! –

+0

Tengo un problema similar que he preguntado aquí http://stackoverflow.com/questions/14410899/unable-to-skip-unreadable-directories-with-recursivedirectoryiterator ¿Tiene alguna idea sobre cómo puedo volver a trabajar con la solución para resolver mi problema? – ak85

+0

Específicamente, la bandera es: CATCH_GET_CHILD –

0

Es posible que la posición del iterador siga siendo válida incluso si un directorio no es legible.

Puede verificar el estado de la entrada en el directorio. Descuidado código de ejemplo no probado:

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

No funciona. Se lanza una excepción cuando el iterador avanza a la siguiente posición. –

7

Usted podría hacer algo como esto:

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"; 
} 
+0

Eso es muy interesante. –

Cuestiones relacionadas