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ć.


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

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

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

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


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";
}

2

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


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

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.