¿Script PHP para recorrer todos los archivos en un directorio?


131

Estoy buscando un script PHP que recorra todos los archivos de un directorio para poder hacer cosas con el nombre del archivo, como formatear, imprimir o agregarlo a un enlace. Me gustaría poder ordenar los archivos por nombre, tipo o por fecha de creación / agregado / modificación. (Piense en el elegante directorio "index"). También me gustaría poder agregar exclusiones a la lista de archivos, como el script en sí u otros archivos del "sistema". (Al igual que los .y .."directorios".)

Siendo que me gustaría poder modificar el script, estoy más interesado en mirar los documentos PHP y aprender a escribir uno yo mismo. Dicho esto, si hay scripts, tutoriales y demás, por favor hágamelo saber.


Respuestas:


245

Puede usar DirectoryIterator . Ejemplo del manual de php:

<?php
$dir = new DirectoryIterator(dirname(__FILE__));
foreach ($dir as $fileinfo) {
    if (!$fileinfo->isDot()) {
        var_dump($fileinfo->getFilename());
    }
}
?>

3
Nota: muchos servidores no tienen SPL instalado, por lo que no podrá utilizar la clase DirectoryIterator (consulte mi publicación alternativa a continuación). ¡Usa esto si puedes!
NexusRex

44
Nota [2]: asegúrese de comprender que la dirname()función anterior obtendrá la carpeta principal de cualquier ruta que coloque allí. En mi caso, supuse que dirname era un contenedor para el nombre / ruta del directorio, por lo que no era necesario.
willdanceforfun

Además, si dirname es un sistema de archivos grande, los problemas con la memoria son evidentes. En mi caso con 1 millón de archivos, la aplicación necesita ~ 512M de ram en memory_limit.
abkrim

1
Si necesita la ruta completa como el /home/examples/banana.jpguso$fileinfo->getPathname()
mgutt

Puede usar! $ Fileinfo-> isDir () para evitar acciones en los directorios
LeChatNoir

44

Si no tiene acceso a la clase DirectoryIterator intente esto:

<?php
$path = "/path/to/files";

if ($handle = opendir($path)) {
    while (false !== ($file = readdir($handle))) {
        if ('.' === $file) continue;
        if ('..' === $file) continue;

        // do something with the file
    }
    closedir($handle);
}
?>

44
¿Puedes nombrar una situación en la que no tendrías acceso a ella?
Jochem Kuijpers

12
Muchas aplicaciones heredadas usan PHP 4, que no tiene acceso al DirectoryIterator.
Joseph Callaars

1
Por qué '.' === $ archivo? Esto no es Java.
Dave Heq

2
Dave ... No, está haciendo coincidir los puntos y no continúa si no coincide en PHP. Busque la diferencia entre == y ===.
JSG

22

Usa la scandir()función:

<?php
    $directory = '/path/to/files';

    if (!is_dir($directory)) {
        exit('Invalid diretory path');
    }

    $files = array();
    foreach (scandir($directory) as $file) {
        if ($file !== '.' && $file !== '..') {
            $files[] = $file;
        }
    }

    var_dump($files);
?>

18

También puedes hacer uso de FilesystemIterator. Requiere aún menos código entonces DirectoryIterator, y automáticamente elimina .y ...

// Let's traverse the images directory
$fileSystemIterator = new FilesystemIterator('images');

$entries = array();
foreach ($fileSystemIterator as $fileInfo){
    $entries[] = $fileInfo->getFilename();
}

var_dump($entries);

//OUTPUT
object(FilesystemIterator)[1]

array (size=14)
  0 => string 'aa[1].jpg' (length=9)
  1 => string 'Chrysanthemum.jpg' (length=17)
  2 => string 'Desert.jpg' (length=10)
  3 => string 'giphy_billclinton_sad.gif' (length=25)
  4 => string 'giphy_shut_your.gif' (length=19)
  5 => string 'Hydrangeas.jpg' (length=14)
  6 => string 'Jellyfish.jpg' (length=13)
  7 => string 'Koala.jpg' (length=9)
  8 => string 'Lighthouse.jpg' (length=14)
  9 => string 'Penguins.jpg' (length=12)
  10 => string 'pnggrad16rgb.png' (length=16)
  11 => string 'pnggrad16rgba.png' (length=17)
  12 => string 'pnggradHDrgba.png' (length=17)
  13 => string 'Tulips.jpg' (length=10)

Enlace: http://php.net/manual/en/class.filesystemiterator.php


5

Puede usar este código para recorrer un directorio de forma recursiva :

$path = "/home/myhome";
$rdi = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_PATHNAME);
foreach (new RecursiveIteratorIterator($rdi, RecursiveIteratorIterator::SELF_FIRST) as $file => $info) {
    echo $file."\n";
}

2

glob () tiene disposiciones para ordenar y hacer coincidir patrones. Como el valor de retorno es una matriz, puede hacer casi todo lo que necesite.


1
Esto es bueno a menos que esté lidiando con muchos archivos ...> 10,000. Te quedarás sin memoria.
NexusRex

@NexusRex: Usted no debe estar leyendo 10.000 registros de una base de datos o bien, pero que está fuera de alcance en lo que se refiere a la cuestión
bcosca

¡Convenido! Sin embargo, si lee desde una base de datos, puede paginar con "límite"; no tiene tanta suerte cuando tiene un directorio con 5 millones de archivos XML para recorrer.
NexusRex

Hay SPL GlobIterator.
przemo_li

2

Para completar (ya que esta parece ser una página de alto tráfico), no olvidemos la buena dir()función anterior :

$entries = [];
$d = dir("/"); // dir to scan
while (false !== ($entry = $d->read())) { // mind the strict bool check!
    if ($entry[0] == '.') continue; // ignore anything starting with a dot
    $entries[] = $entry;
}
$d->close();
sort($entries); // or whatever desired

print_r($entries);
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.