Script PHP pour parcourir tous les fichiers d'un répertoire?

131

Je recherche un script PHP qui parcourt tous les fichiers d'un répertoire afin que je puisse faire des choses avec le nom de fichier, comme le format, l'imprimer ou l'ajouter à un lien. Je voudrais pouvoir trier les fichiers par nom, type ou par date de création / ajoutée / modifiée. (Pensez à "index" de répertoire de fantaisie.) J'aimerais également pouvoir ajouter des exclusions à la liste de fichiers, comme le script lui-même ou d'autres fichiers "système". (Comme .et ..« répertoires ».)

Étant donné que j'aimerais pouvoir modifier le script, je suis plus intéressé par la documentation PHP et par apprendre à en écrire un moi-même. Cela dit, s'il existe des scripts, des didacticiels, etc., veuillez me le faire savoir.

Moshe
la source

Réponses:

245

Vous pouvez utiliser DirectoryIterator . Exemple du manuel php:

<?php
$dir = new DirectoryIterator(dirname(__FILE__));
foreach ($dir as $fileinfo) {
    if (!$fileinfo->isDot()) {
        var_dump($fileinfo->getFilename());
    }
}
?>
Morfildur
la source
3
Remarque: de nombreux serveurs n'ont pas installé SPL, vous ne pourrez donc pas utiliser la classe DirectoryIterator (voir mon article alternatif ci-dessous). Utilisez ceci si vous le pouvez!
NexusRex
4
Remarque [2]: assurez-vous que vous comprenez que la dirname()fonction ci-dessus obtiendra le dossier parent du chemin que vous y mettez. Dans mon cas, j'ai supposé que dirname était un wrapper pour le nom / chemin du répertoire, donc ce n'était pas nécessaire.
willdanceforfun
De plus, si dirname est un système de fichiers volumineux, les problèmes de mémoire sont évidents. Dans mon cas avec 1 million de fichiers, l'application a besoin d'environ 512 Mo de RAM sur memory_limit.
abkrim
1
Si vous avez besoin du chemin complet comme /home/examples/banana.jpgutiliser$fileinfo->getPathname()
mgutt
Vous pouvez utiliser! $ Fileinfo-> isDir () pour éviter l'action sur les répertoires
LeChatNoir
44

Si vous n'avez pas accès à la classe DirectoryIterator, essayez ceci:

<?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
la source
4
Pouvez-vous nommer une situation où vous n'y auriez pas accès?
Jochem Kuijpers
12
De nombreuses applications héritées utilisent PHP 4, qui n'a pas accès à DirectoryIterator.
Joseph Callaars
1
Pourquoi '.' === $ fichier? Ce n'est pas Java.
Dave Heq
2
Dave ... Non, il correspond aux points et ne continue pas s'il ne correspond pas en PHP. Recherchez la différence entre == et ===.
JSG
22

Utilisez la scandir()fonction:

<?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
la source
18

Vous pouvez également utiliser FilesystemIterator. Il nécessite encore moins de code DirectoryIteratoret supprime automatiquement .et ...

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

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

julien
la source
5

Vous pouvez utiliser ce code pour parcourir un répertoire de manière récursive :

$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
la source
2

glob () a des dispositions pour le tri et la correspondance de modèles. La valeur de retour étant un tableau, vous pouvez faire la plupart de tout ce dont vous avez besoin.

bcosca
la source
1
C'est bien sauf si vous avez affaire à beaucoup de fichiers ...> 10 000. Vous manquerez de mémoire.
NexusRex
@NexusRex: Vous ne devriez pas non plus lire 10000 enregistrements d'une base de données, mais c'est hors de portée en ce qui concerne la question
bcosca
D'accord! Si vous lisez à partir d'une base de données, vous pouvez paginer avec "limit" cependant - pas de chance lorsque vous avez un répertoire avec 5 millions de fichiers XML à parcourir.
NexusRex
Il y a SPL GlobIterator.
przemo_li
2

Par souci d'exhaustivité (puisque cela semble être une page à fort trafic), n'oublions pas la bonne vieille dir()fonction :

$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.
la source