Script PHP para percorrer todos os arquivos em um diretório?


131

Estou procurando um script PHP que percorre todos os arquivos em um diretório para que eu possa fazer coisas com o nome do arquivo, como formatar, imprimir ou adicioná-lo a um link. Gostaria de poder classificar os arquivos por nome, tipo ou data criada / adicionada / modificada. (Pense no diretório "índice" sofisticado.) Também gostaria de poder adicionar exclusões à lista de arquivos, como o próprio script ou outros arquivos do "sistema". (Como os diretórios " .e ..".)

Sendo que eu gostaria de modificar o script, estou mais interessado em examinar os documentos PHP e aprender a escrever um. Dito isto, se houver scripts, tutoriais e outros itens existentes, entre em contato.


Respostas:


245

Você pode usar o DirectoryIterator . Exemplo do Manual do php:

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

3
Nota: muitos servidores não possuem o SPL instalado; portanto, você não poderá usar a classe DirectoryIterator (veja minha postagem alternativa abaixo). Use isso se puder!
NexusRex

4
Nota [2]: Certifique-se de entender que a dirname()função acima obterá a pasta pai de qualquer caminho que você colocar lá. No meu caso, assumi que o dirname era um wrapper para o nome do diretório / caminho, portanto não era necessário.
willdanceforfun

Além disso, se dirname for um sistema de arquivos grande, problemas com memória são evidentes. No meu caso, com 1 milhão de arquivos, o aplicativo precisa de ~ 512M de memória ram no memory_limit.
abkrim

1
Se você precisa do caminho completo como /home/examples/banana.jpgo uso$fileinfo->getPathname()
mgutt

Você pode usar $ fileinfo-> isDir () para Ação Evite em diretórios!
LeChatNoir

44

Se você não tem acesso à classe DirectoryIterator, tente o seguinte:

<?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
Você pode citar uma situação em que não teria acesso a ela?
Jochem Kuijpers

12
Muitos aplicativos herdados usam o PHP 4, que não tem acesso ao DirectoryIterator.
Joseph Callaars

1
Por quê '.' === $ arquivo? Isto não é Java.
Dave Heq

2
Dave ... Não, ele corresponde aos pontos e não continua se não corresponder no PHP. Procure a diferença entre == e ===.
JSG

22

Use a scandir()função:

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

Você também pode fazer uso FilesystemIterator. Exige ainda menos código DirectoryIteratore remove .e automaticamente ...

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

Você pode usar esse código para percorrer um diretório recursivamente :

$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 () possui provisões para classificação e correspondência de padrões. Como o valor de retorno é uma matriz, você pode fazer quase tudo o que precisa.


1
Isso é bom, a menos que você esteja lidando com muitos arquivos ...> 10.000. Você ficará sem memória.
NexusRex

@NexusRex: Você não deve estar lendo 10.000 registros de um banco de dados de qualquer um, mas que está fora de alcance, tanto quanto a questão está em causa
bcosca

Acordado! Se estiver lendo de um banco de dados, você pode paginar com "limite" - sem essa sorte quando tiver um diretório com 5 milhões de arquivos XML para percorrer.
NexusRex

Existe o SPL GlobIterator.
Przemo_li 5/09

2

Para garantir a integridade (já que essa parece ser uma página de alto tráfego), não vamos esquecer a boa e antiga dir()função :

$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);
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.