Script PHP untuk mengulang semua file dalam direktori?


131

Saya sedang mencari skrip PHP yang loop melalui semua file dalam direktori sehingga saya dapat melakukan hal-hal dengan nama file, seperti memformat, mencetak atau menambahkannya ke sebuah tautan. Saya ingin dapat mengurutkan file berdasarkan nama, jenis atau berdasarkan tanggal dibuat / ditambahkan / dimodifikasi. (Pikirkan direktori mewah "indeks".) Saya juga ingin dapat menambahkan pengecualian ke daftar file, seperti skrip itu sendiri atau file "sistem" lainnya. (Seperti .dan .."direktori".)

Karena saya ingin dapat memodifikasi skrip, saya lebih tertarik melihat dokumen PHP dan belajar bagaimana menulisnya sendiri. Yang mengatakan, jika ada skrip yang ada, tutorial dan yang lainnya, tolong beri tahu saya.


Jawaban:


245

Anda dapat menggunakan DirectoryIterator . Contoh dari php Manual:

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

3
Catatan: banyak server tidak menginstal SPL, jadi Anda tidak akan dapat menggunakan kelas DirectoryIterator (lihat posting alternatif saya di bawah). Gunakan ini jika Anda bisa!
NexusRex

4
Catatan [2]: Pastikan Anda memahami bahwa dirname()fungsi di atas akan mendapatkan folder induk dari jalur apa pun yang Anda letakkan di sana. Dalam kasus saya, saya menganggap dirname adalah pembungkus untuk nama direktori / path, jadi itu tidak diperlukan.
willdanceforfun

Juga, jika dirname itu adalah sistem file besar, masalah dengan memori jelas. Dalam kasus saya dengan 1 juta file, aplikasi membutuhkan ram ~ 512M pada memory_limit.
abkrim

1
Jika Anda memerlukan path lengkap seperti /home/examples/banana.jpggunakan$fileinfo->getPathname()
mgutt

Anda dapat menggunakan! $ Fileinfo-> isDir () untuk menghindari tindakan pada direktori
LeChatNoir

44

Jika Anda tidak memiliki akses ke kelas DirectoryIterator coba ini:

<?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
Bisakah Anda menyebutkan situasi di mana Anda tidak akan memiliki akses ke situ?
Jochem Kuijpers

12
Banyak aplikasi lawas menggunakan PHP 4, yang tidak memiliki akses ke DirectoryIterator.
Joseph Callaars

1
Kenapa '.' === $ file? Ini bukan Java.
Dave Heq

2
Dave ... Tidak, itu cocok dengan titik-titik dan tidak berlanjut jika tidak cocok di PHP. Cari perbedaan antara == dan ===.
JSG

22

Gunakan scandir()fungsinya:

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

Anda juga dapat memanfaatkan FilesystemIterator. Itu membutuhkan lebih sedikit kode kemudian DirectoryIterator, dan secara otomatis menghapus .dan ...

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

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


5

Anda dapat menggunakan kode ini untuk mengulang melalui direktori secara rekursif :

$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 () memiliki ketentuan untuk penyortiran dan pencocokan pola. Karena nilai kembali adalah array, Anda dapat melakukan sebagian besar dari semua yang Anda butuhkan.


1
Ini bagus kecuali Anda berurusan dengan banyak file ...> 10.000. Anda akan kehabisan memori.
NexusRex

@NexusRex: Anda juga seharusnya tidak membaca 10.000 catatan dari database, tapi itu di luar jangkauan sejauh menyangkut pertanyaan
bcosca

Sepakat! Jika membaca dari basis data, Anda dapat menggunakan pagination dengan "limit" —tidak beruntung ketika Anda memiliki direktori dengan 5 juta file XML untuk diulangi.
NexusRex

Ada SPL GlobIterator.
przemo_li

2

Untuk kelengkapan (karena ini tampaknya halaman dengan lalu lintas tinggi), jangan lupa dir()fungsi lama yang baik :

$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);
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.