Script PHP per scorrere tutti i file in una directory?


131

Sto cercando uno script PHP che esegua il ciclo attraverso tutti i file in una directory in modo da poter fare cose con il nome del file, come formato, stampa o aggiungerlo a un collegamento. Mi piacerebbe poter ordinare i file per nome, tipo o data di creazione / aggiunta / modifica. (Pensa alla directory "indice" di fantasia.) Vorrei anche poter aggiungere esclusioni all'elenco di file, come lo script stesso o altri file "di sistema". (Come il .e .."directory".)

Essendo che vorrei poter modificare la sceneggiatura, sono più interessato a guardare i documenti PHP e imparare a scriverne uno da solo. Detto questo, se ci sono script, tutorial e quant'altro esistenti, per favore fatemelo sapere.


Risposte:


245

È possibile utilizzare DirectoryIterator . Esempio dal manuale di php:

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

3
Nota: molti server non hanno SPL installato, quindi non sarai in grado di utilizzare la classe DirectoryIterator (vedi il mio post alternativo di seguito). Usa questo se puoi però!
NexusRex,

4
Nota [2]: assicurati di aver compreso che la dirname()funzione precedente otterrà la cartella principale di qualunque percorso hai inserito. Nel mio caso, ho ipotizzato che dirname fosse un wrapper per il nome / percorso della directory, quindi non era necessario.
Willdanceforfun,

Inoltre, se dirname è un file system di grandi dimensioni, i problemi con la memoria sono evidenti. Nel mio caso con 1 milione di file, l'app richiede ~ 512 M di RAM su memory_limit.
abkrim,

1
Se hai bisogno del percorso completo come /home/examples/banana.jpgusare$fileinfo->getPathname()
mgutt

Puoi usare! $ Fileinfo-> isDir () per evitare azioni sulle directory
LeChatNoir

44

Se non hai accesso alla classe DirectoryIterator prova questo:

<?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);
}
?>

4
Puoi nominare una situazione in cui non avresti accesso ad essa?
Jochem Kuijpers,

12
Molte applicazioni legacy utilizzano PHP 4, che non ha accesso a DirectoryIterator.
Joseph Callaars,

1
Perché '.' === $ file? Questo non è Java.
Dave Heq,

2
Dave ... No, corrisponde ai punti e non continua se non corrisponde in PHP. Cerca la differenza tra == e ===.
JSG

22

Usa la scandir()funzione:

<?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

Puoi anche farne uso FilesystemIterator. Richiede ancora meno codice DirectoryIterator, quindi rimuove automaticamente .e ...

// 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)

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


5

È possibile utilizzare questo codice per ricorrere in modo ricorsivo a una directory :

$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 () ha disposizioni per l'ordinamento e la corrispondenza dei modelli. Poiché il valore restituito è un array, puoi fare quasi tutto il resto di cui hai bisogno.


1
Questo va bene se non hai a che fare con molti file ...> 10.000. Non avrai più memoria.
NexusRex,

@NexusRex: Non dovresti leggere neanche 10.000 record da un database, ma questo è fuori portata per quanto riguarda la domanda
bcosca,

Concordato! Se stai leggendo da un database puoi però impaginare con "limit" - nessuna fortuna se hai una directory con 5 milioni di file XML da scorrere.
NexusRex,

C'è SPL GlobIterator.
przemo_li,

2

Per completezza (poiché questa sembra essere una pagina a traffico elevato), non dimentichiamo la buona vecchia dir()funzione :

$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);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.