สคริปต์ PHP เพื่อวนซ้ำไฟล์ทั้งหมดในไดเร็กทอรี?


137

ฉันกำลังมองหาสคริปต์ PHP ที่วนซ้ำไฟล์ทั้งหมดในไดเร็กทอรีดังนั้นฉันจึงสามารถทำสิ่งต่างๆกับชื่อไฟล์เช่นรูปแบบพิมพ์หรือเพิ่มลงในลิงก์ ฉันต้องการจัดเรียงไฟล์ตามชื่อประเภทหรือตามวันที่สร้าง / เพิ่ม / แก้ไข (คิดว่าไดเร็กทอรีแฟนซี "ดัชนี") ฉันต้องการเพิ่มการยกเว้นในรายการไฟล์เช่นตัวสคริปต์เองหรือไฟล์ "ระบบ" อื่น ๆ (เช่น.และ.."ไดเรกทอรี")

เนื่องจากฉันต้องการแก้ไขสคริปต์ฉันสนใจที่จะดูเอกสาร PHP และเรียนรู้วิธีการเขียนด้วยตัวเองมากขึ้น ที่กล่าวว่าหากมีสคริปต์บทช่วยสอนและไม่มีอะไรอยู่โปรดแจ้งให้เราทราบ


คำตอบ:


251

คุณสามารถใช้DirectoryIterator ตัวอย่างจากคู่มือ php:

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

3
หมายเหตุ: เซิร์ฟเวอร์จำนวนมากไม่ได้ติดตั้ง SPL ดังนั้นคุณจะไม่สามารถใช้คลาส DirectoryIterator ได้ (ดูโพสต์ทางเลือกของฉันด้านล่าง) ใช้สิ่งนี้ถ้าคุณทำได้!
NexusRex

5
หมายเหตุ [2]: ตรวจสอบให้แน่ใจว่าคุณเข้าใจว่าdirname()ฟังก์ชันข้างต้นจะได้รับโฟลเดอร์หลักของเส้นทางใด ๆ ที่คุณใส่ไว้ที่นั่น ในกรณีของฉันฉันคิดว่า dirname เป็น wrapper สำหรับชื่อไดเร็กทอรี / พา ธ ดังนั้นจึงไม่จำเป็น
willdanceforfun

นอกจากนี้หาก dirname เป็นระบบไฟล์ขนาดใหญ่ปัญหาเกี่ยวกับหน่วยความจำจะชัดเจน ในกรณีของฉันที่มีไฟล์ 1 ล้านแอปต้องการ ram ~ 512M บน memory_limit
abkrim

1
หากคุณต้องการเส้นทางที่สมบูรณ์เช่น/home/examples/banana.jpguse$fileinfo->getPathname()
mgutt

คุณสามารถใช้! $ fileinfo-> isDir () เพื่อหลีกเลี่ยงการดำเนินการกับไดเรกทอรี
LeChatNoir

44

หากคุณไม่มีสิทธิ์เข้าถึงคลาส DirectoryIterator ให้ลองสิ่งนี้:

<?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
คุณสามารถตั้งชื่อสถานการณ์ที่คุณไม่สามารถเข้าถึงได้หรือไม่?
Jochem Kuijpers

12
แอปพลิเคชันเดิมจำนวนมากใช้ PHP 4 ซึ่งไม่มีสิทธิ์เข้าถึง DirectoryIterator
Joseph Callaars

1
ทำไม '.' === $ ไฟล์? นี่ไม่ใช่ Java
Dave Heq

2
Dave ... ไม่ว่ามันจะจับคู่จุดและไม่ดำเนินการต่อหากไม่ตรงกันใน PHP ค้นหาความแตกต่างระหว่าง == และ ===
JSG

23

ใช้scandir()ฟังก์ชัน:

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

คุณยังสามารถใช้ประโยชน์จากFilesystemIteratorไฟล์. มันต้องมีรหัสแม้แต่น้อยแล้วDirectoryIteratorและลบโดยอัตโนมัติและ...

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

ลิงค์: http://php.net/manual/en/class.filesystemiterator.php


5

คุณสามารถใช้รหัสนี้เพื่อวนซ้ำในไดเรกทอรีแบบวนซ้ำ :

$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 ()มีข้อกำหนดสำหรับการเรียงลำดับและการจับคู่รูปแบบ เนื่องจากค่าที่ส่งคืนเป็นอาร์เรย์คุณจึงสามารถทำทุกอย่างที่ต้องการได้เกือบทั้งหมด


1
นี่เป็นสิ่งที่ดีเว้นแต่คุณจะจัดการกับไฟล์จำนวนมาก ... > 10,000 หน่วยความจำคุณจะหมด
NexusRex

@NexusRex: คุณไม่ควรอ่าน 10,000 บันทึกจากฐานข้อมูลด้วยเช่นกัน แต่มันอยู่นอกขอบเขตเท่าที่เป็นปัญหา
bcosca

เห็นด้วย! หากอ่านจากฐานข้อมูลคุณสามารถกำหนดเลขหน้าด้วย "ขีด จำกัด " ได้ แต่ก็ไม่มีโชคเช่นนี้เมื่อคุณมีไดเร็กทอรีที่มีไฟล์ XML 5 ล้านไฟล์ให้วนซ้ำ
NexusRex

มี SPL GlobIterator
przemo_li

2

เพื่อความสมบูรณ์ (เนื่องจากดูเหมือนว่าจะเป็นหน้าที่มีการเข้าชมสูง) อย่าลืมdir()ฟังก์ชันเก่า ๆ ที่ดี:

$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

ส่วนใหญ่เวลาที่ฉันคิดว่าคุณต้องการที่จะข้ามและ. ..นี่คือการเรียกซ้ำ:

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.