Bir dizindeki tüm dosyalar arasında döngü yapmak için PHP betiği?


131

Bir dizindeki tüm dosyalar arasında döngü yapan bir PHP betiği arıyorum, böylece dosya adı ile format, yazdırma veya bir bağlantıya ekleme gibi şeyler yapabilirim. Dosyaları ada, türe veya oluşturulma / eklenme / değiştirilme tarihine göre sıralayabilmek istiyorum. (Fantezi dizin "indeksini" düşünün.) Ayrıca, komut dosyasının kendisi veya diğer "sistem" dosyaları gibi dosya listesine istisnalar da eklemek istiyorum. ( .Ve .."dizinler" gibi.)

Betiği değiştirebilmek istediğim için, PHP belgelerine bakmak ve kendim nasıl yazacağımı öğrenmekle daha çok ilgileniyorum. Bununla birlikte, mevcut herhangi bir komut dosyası, öğretici vb. Varsa lütfen bana bildirin.


Yanıtlar:


245

DirectoryIterator'ı kullanabilirsiniz . Php Kılavuzundan örnek:

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

3
Not: Birçok sunucuda SPL kurulu değildir, bu nedenle DirectoryIterator sınıfını kullanamazsınız (aşağıdaki alternatif yazıma bakın). Yapabiliyorsanız bunu kullanın!
NexusRex

4
Not [2]: dirname()Yukarıdaki işlevin, oraya koyduğunuz yolun ana klasörünü alacağını anladığınızdan emin olun . Benim durumumda, dirname'nin dizin adı / yolu için bir sarmalayıcı olduğunu varsaydım, bu yüzden buna gerek yoktu.
willdanceforfun

Ayrıca, dirname büyük bir dosya sistemiyse, bellekle ilgili sorunlar belirgindir. 1 milyon dosya içeren durumumda, uygulamanın memory_limit'te ~ 512M ram'a ihtiyacı var.
abkrim

1
/home/examples/banana.jpgKullanım gibi tam yola ihtiyacınız varsa$fileinfo->getPathname()
mgutt

Dizinler üzerinde işlem yapılmasını önlemek için! $ Fileinfo-> isDir () komutunu kullanabilirsiniz
LeChatNoir

44

DirectoryIterator sınıfına erişiminiz yoksa şunu deneyin:

<?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
Erişiminizin olmadığı bir durumu adlandırabilir misiniz?
Jochem Kuijpers

12
Birçok eski uygulama, DirectoryIterator'a erişimi olmayan PHP 4'ü kullanır.
Joseph Callaars

1
Neden '.' === $ dosya? Bu Java değil.
Dave Heq

2
Dave ... Hayır, noktalarla eşleşiyor ve PHP'de eşleşmezse devam etmiyor. == ve === arasındaki farkı arayın.
JSG

22

Şu scandir()işlevi kullanın :

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

Ayrıca yararlanabilirsiniz FilesystemIterator. O zaman daha da az kod gerektirir DirectoryIteratorve otomatik olarak kaldırır .ve ...

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

Bağlantı: http://php.net/manual/en/class.filesystemiterator.php


5

Bir dizinde özyinelemeli döngü yapmak için bu kodu kullanabilirsiniz :

$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 () , sıralama ve örüntü eşleştirme için hükümlere sahiptir. Dönüş değeri bir dizi olduğundan, ihtiyacınız olan her şeyin çoğunu yapabilirsiniz.


1
Çok fazla dosya ile uğraşmadığınız sürece bu iyidir ...> 10.000. Hafızanız bitecek.
NexusRex

@NexusRex: Bir veritabanından 10.000 kayıt da okumamalısınız, ancak soru söz konusu olduğunda kapsam dışı
bcosca

Kabul! Bir veritabanından okuyorsanız, "sınırla" sayfalandırabilirsiniz — yinelemeniz gereken 5 milyon XML dosyası olan bir dizininiz olduğunda böyle bir şans yoktur.
NexusRex

SPL GlobIterator var.
przemo_li

2

Tamlık için (bu yüksek trafikli bir sayfa gibi göründüğünden), eski güzel dir()işlevi unutmayalım :

$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);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.