¿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.

Moshe
fuente

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());
    }
}
?>
Morfildur
fuente
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);
}
?>
NexusRex
fuente
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);
?>
ChorData
fuente
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

Julian
fuente
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";
}
GameScripting
fuente
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.

bcosca
fuente
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);
Sz.
fuente