Tập lệnh PHP để lặp qua tất cả các tệp trong một thư mục?


131

Tôi đang tìm một tập lệnh PHP lặp qua tất cả các tệp trong một thư mục để tôi có thể thực hiện mọi việc với tên tệp, chẳng hạn như định dạng, in hoặc thêm nó vào một liên kết. Tôi muốn có thể sắp xếp các tệp theo tên, loại hoặc theo ngày được tạo / thêm / sửa đổi. (Hãy nghĩ rằng "chỉ mục" thư mục ưa thích.) Tôi cũng muốn có thể thêm các loại trừ vào danh sách các tệp, chẳng hạn như chính tập lệnh hoặc các tệp "hệ thống" khác. (Giống như ..."thư mục".)

Vì tôi muốn có thể sửa đổi tập lệnh, tôi thích thú hơn khi xem các tài liệu PHP và tự học cách viết một tập lệnh. Điều đó nói rằng, nếu có bất kỳ kịch bản, hướng dẫn và không có gì, xin vui lòng cho tôi biết.


Câu trả lời:


245

Bạn có thể sử dụng DirectoryIterator . Ví dụ từ Hướng dẫn sử dụng php:

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

3
Lưu ý: nhiều máy chủ chưa cài đặt SPL, vì vậy bạn sẽ không thể sử dụng lớp DirectoryIterator (xem bài đăng thay thế của tôi bên dưới). Sử dụng điều này nếu bạn có thể mặc dù!
NexusRex

4
Lưu ý [2]: Đảm bảo rằng bạn hiểu rằng dirname()hàm trên sẽ nhận được thư mục mẹ của bất kỳ đường dẫn nào bạn đặt ở đó. Trong trường hợp của tôi, tôi giả sử dirname là một trình bao bọc cho tên / đường dẫn thư mục, vì vậy nó không cần thiết.
willdanceforfun 3/03/2016

Ngoài ra, nếu dirname đó là một hệ thống tập tin lớn, vấn đề với bộ nhớ là hiển nhiên. Trong trường hợp của tôi với 1 triệu tệp, ứng dụng cần ~ 512M ram trên memory_limit.
abkrim

1
Nếu bạn cần đường dẫn đầy đủ như /home/examples/banana.jpgsử dụng$fileinfo->getPathname()
mgutt

Bạn có thể sử dụng! $ Fileinfo-> isDir () để tránh hành động trên các thư mục
LeChatNoir

44

Nếu bạn không có quyền truy cập vào lớp DirectoryIterator, hãy thử điều này:

<?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
Bạn có thể đặt tên cho một tình huống mà bạn sẽ không có quyền truy cập vào nó?
Joool Kuijpers

12
Rất nhiều ứng dụng cũ sử dụng PHP 4, không có quyền truy cập vào DirectoryIterator.
Joseph Callaars

1
Tại sao '.' === $ tập tin? Đây không phải là Java.
Dave Heq

2
Dave ... Không, nó phù hợp với các dấu chấm và không tiếp tục nếu nó không khớp trong PHP. Tìm kiếm sự khác biệt giữa == và ===.
JSG

22

Sử dụng scandir()chức năng:

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

Bạn cũng có thể sử dụng FilesystemIterator. Nó yêu cầu thậm chí ít mã hơn sau đó DirectoryIterator, và tự động loại bỏ ....

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

Liên kết: http://php.net/manual/en/ class.filesystemiterator.php


5

Bạn có thể sử dụng mã này để lặp qua một thư mục đệ quy :

$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

global () có các quy định để sắp xếp và khớp mẫu. Vì giá trị trả về là một mảng, bạn có thể làm hầu hết mọi thứ khác mà bạn cần.


1
Điều này là tốt trừ khi bạn đang xử lý nhiều tệp ...> 10.000. Bạn sẽ hết bộ nhớ.
NexusRex

@NexusRex: Bạn cũng không nên đọc 10.000 bản ghi từ cơ sở dữ liệu, nhưng đó là ngoài phạm vi liên quan đến câu hỏi
bcosca

Đã đồng ý! Nếu đọc từ cơ sở dữ liệu, bạn có thể phân trang với "giới hạn" mặc dù không có may mắn như vậy khi bạn có một thư mục có 5 triệu tệp XML để lặp lại.
NexusRex

Có SPL GlobIterator.
przemo_li

2

Để hoàn thiện (vì đây dường như là một trang có lưu lượng truy cập cao), chúng ta đừng quên dir()chức năng cũ tốt :

$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);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.