PHP-Skript zum Durchlaufen aller Dateien in einem Verzeichnis?

131

Ich suche nach einem PHP-Skript, das alle Dateien in einem Verzeichnis durchläuft, damit ich mit dem Dateinamen Dinge tun kann, wie z. B. Formatieren, Drucken oder Hinzufügen zu einem Link. Ich möchte in der Lage sein, die Dateien nach Name, Typ oder Datum der Erstellung / Hinzufügung / Änderung zu sortieren. (Denken Sie an ein ausgefallenes Verzeichnis "index".) Ich möchte auch Ausschlüsse zur Liste der Dateien hinzufügen können, z. B. das Skript selbst oder andere "System" -Dateien. (Wie die .und .."Verzeichnisse".)

Da ich das Skript ändern möchte, bin ich mehr daran interessiert, mir die PHP-Dokumente anzusehen und zu lernen, wie man selbst eines schreibt. Das heißt, wenn es Skripte, Tutorials und so weiter gibt, lassen Sie es mich bitte wissen.

Moshe
quelle

Antworten:

245

Sie können den DirectoryIterator verwenden . Beispiel aus dem PHP-Handbuch:

<?php
$dir = new DirectoryIterator(dirname(__FILE__));
foreach ($dir as $fileinfo) {
    if (!$fileinfo->isDot()) {
        var_dump($fileinfo->getFilename());
    }
}
?>
Morfildur
quelle
3
Hinweis: Auf vielen Servern ist SPL nicht installiert, sodass Sie die DirectoryIterator-Klasse nicht verwenden können (siehe meinen alternativen Beitrag unten). Verwenden Sie dies, wenn Sie können!
NexusRex
4
Hinweis [2]: Stellen Sie sicher, dass Sie verstehen, dass die dirname()obige Funktion den übergeordneten Ordner des dort angegebenen Pfads abruft. In meinem Fall habe ich angenommen, dass dirname ein Wrapper für den Verzeichnisnamen / -pfad ist, sodass er nicht benötigt wird.
Willdanceforfun
Wenn es sich bei dirname um ein großes Dateisystem handelt, sind Probleme mit dem Speicher offensichtlich. In meinem Fall mit 1 Million Dateien benötigt die App ~ 512 MB RAM auf memory_limit.
Abkrim
1
Wenn Sie den vollständigen Pfad wie /home/examples/banana.jpgverwenden müssen$fileinfo->getPathname()
mgutt
Sie können! $ Fileinfo-> isDir () verwenden, um Aktionen in Verzeichnissen zu vermeiden
LeChatNoir
44

Wenn Sie keinen Zugriff auf die DirectoryIterator-Klasse haben, versuchen Sie Folgendes:

<?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
quelle
4
Können Sie eine Situation nennen, in der Sie keinen Zugriff darauf hätten?
Jochem Kuijpers
12
Viele ältere Anwendungen verwenden PHP 4, das keinen Zugriff auf den DirectoryIterator hat.
Joseph Callaars
1
Warum '.' === $ file? Dies ist nicht Java.
Dave Heq
2
Dave ... Nein, es stimmt mit den Punkten überein und wird nicht fortgesetzt, wenn es in PHP nicht übereinstimmt. Suchen Sie nach dem Unterschied zwischen == und ===.
JSG
22

Verwenden Sie die scandir()Funktion:

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

Sie können auch nutzen FilesystemIterator. Es benötigt dann noch weniger Code DirectoryIteratorund entfernt .und automatisch ...

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

julianisch
quelle
5

Mit diesem Code können Sie ein Verzeichnis rekursiv durchlaufen :

$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
quelle
2

glob () enthält Bestimmungen zum Sortieren und Abgleichen von Mustern. Da der Rückgabewert ein Array ist, können Sie fast alles andere tun, was Sie benötigen.

bcosca
quelle
1
Dies ist gut, es sei denn, Sie haben es mit vielen Dateien zu tun ...> 10.000. Ihnen wird der Speicher ausgehen.
NexusRex
@NexusRex: Sie sollten auch nicht 10.000 Datensätze aus einer Datenbank lesen, aber das ist in Bezug auf die Frage nicht möglich
bcosca
Einverstanden! Wenn Sie aus einer Datenbank lesen, können Sie jedoch mit "limit" paginieren - kein Glück, wenn Sie ein Verzeichnis mit 5 Millionen XML-Dateien zum Durchlaufen haben.
NexusRex
Es gibt SPL GlobIterator.
przemo_li
2

Der Vollständigkeit halber (da dies eine stark frequentierte Seite zu sein scheint) sollten wir die gute alte dir()Funktion nicht vergessen :

$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);
Gr.
quelle