Skrypt PHP do przeglądania wszystkich plików w katalogu?

137

Szukam skryptu PHP, który przegląda wszystkie pliki w katalogu, dzięki czemu mogę robić rzeczy z nazwą pliku, takie jak formatowanie, drukowanie lub dodawanie do łącza. Chciałbym móc sortować pliki według nazwy, typu lub daty utworzenia / dodania / modyfikacji. (Pomyśl o fantazyjnym katalogu „index”.) Chciałbym również móc dodawać wyłączenia do listy plików, takie jak sam skrypt lub inne pliki „systemowe”. (Jak .i ..„katalogów”).

Ponieważ chciałbym móc modyfikować skrypt, bardziej interesuje mnie przeglądanie dokumentacji PHP i nauka samodzielnego pisania. To powiedziawszy, jeśli istnieją jakieś skrypty, samouczki i inne, daj mi znać.

Mosze
źródło

Odpowiedzi:

251

Możesz użyć DirectoryIterator . Przykład z podręcznika php:

<?php
$dir = new DirectoryIterator(dirname(__FILE__));
foreach ($dir as $fileinfo) {
    if (!$fileinfo->isDot()) {
        var_dump($fileinfo->getFilename());
    }
}
?>
Morfildur
źródło
3
Uwaga: wiele serwerów nie ma zainstalowanego SPL, więc nie będziesz mógł używać klasy DirectoryIterator (zobacz mój alternatywny wpis poniżej). Użyj tego, jeśli możesz!
NexusRex
5
Uwaga [2]: Upewnij się, że rozumiesz, że dirname()powyższa funkcja uzyska folder nadrzędny dowolnej ścieżki, którą tam umieścisz. W moim przypadku założyłem, że nazwa katalogu była opakowaniem dla nazwy katalogu / ścieżki, więc nie była potrzebna.
willdanceforfun
Ponadto, jeśli dirname to duży system plików, problemy z pamięcią są ewidentne. W moim przypadku z 1 milionem plików aplikacja potrzebuje ~ 512 MB pamięci RAM na memory_limit.
abkrim
1
Jeśli potrzebujesz pełnej ścieżki, takiej jak /home/examples/banana.jpgużyj$fileinfo->getPathname()
mgutt
Możesz użyć! $ Fileinfo-> isDir (), aby uniknąć akcji na katalogach
LeChatNoir
44

Jeśli nie masz dostępu do klasy DirectoryIterator, spróbuj tego:

<?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
źródło
4
Czy możesz wymienić sytuację, w której nie miałbyś do niej dostępu?
Jochem Kuijpers,
12
Wiele starszych aplikacji używa PHP 4, które nie mają dostępu do DirectoryIterator.
Joseph Callaars
1
Czemu '.' === $ plik? To nie jest Java.
Dave Heq
2
Dave ... Nie, dopasowuje kropki i nie kontynuuje, jeśli nie pasuje w PHP. Wyszukaj różnicę między == i ===.
JSG,
23

Użyj scandir()funkcji:

<?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
źródło
18

Możesz także skorzystać z FilesystemIterator. Wymaga wtedy jeszcze mniej kodu DirectoryIteratori automatycznie usuwa .i ...

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

juliański
źródło
5

Możesz użyć tego kodu, aby zapętlić katalog rekurencyjnie :

$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
źródło
2

glob () zawiera przepisy dotyczące sortowania i dopasowywania wzorców. Ponieważ wartość zwracana jest tablicą, możesz zrobić większość wszystkiego, czego potrzebujesz.

bcosca
źródło
1
To jest dobre, chyba że masz do czynienia z dużą liczbą plików ...> 10 000. Skończy ci się pamięć.
NexusRex
@NexusRex: Nie powinieneś też czytać 10000 rekordów z bazy danych, ale to jest poza zakresem, jeśli chodzi o pytanie
bcosca
Zgoda! Jeśli czytasz z bazy danych, możesz jednak paginować z „limitem” - nie ma szczęścia, gdy masz katalog z 5 milionami plików XML do iteracji.
NexusRex
Jest SPL GlobIterator.
przemo_li
2

Aby uzyskać kompletność (ponieważ wydaje się, że jest to strona o dużym natężeniu ruchu), nie zapomnijmy o starej, dobrej dir()funkcji :

$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.
źródło
0

Przez większość czasu wyobrażam sobie, że chcesz pominąć .i ... Oto to z rekurencją:

<?php
$o_dir = new RecursiveDirectoryIterator('.', FilesystemIterator::SKIP_DOTS);
$o_iter = new RecursiveIteratorIterator($o_dir);
foreach ($o_iter as $o_name) {
   echo $o_name->getFilename();
}

https://php.net/class.recursivedirectoryiterator

Steven Penny
źródło