PHP脚本循环遍历目录中的所有文件?


131

我正在寻找一个循环遍历目录中所有文件的PHP脚本,以便可以使用文件名进行操作,例如格式,打印或将其添加到链接中。我希望能够按名称,类型或创建/添加/修改的日期对文件进行排序。(想想目录“ index”。)我还希望能够将排除项添加到文件列表中,例如脚本本身或其他“系统”文件。(类似于...“目录”。)

由于我希望能够修改脚本,因此我对查看PHP文档和学习如何自己编写更感兴趣。就是说,如果有任何现有的脚本,教程等,请告诉我。


Answers:


245

您可以使用DirectoryIterator。来自PHP手册的示例:

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

3
注意:许多服务器未安装SPL,因此您将无法使用DirectoryIterator类(请参阅下面的我的替代文章)。如果可以,请使用此功能!
NexusRex 2011年

4
注意[2]:请确保您理解dirname()上面的函数将获取您放置在其中的任何路径的父文件夹。就我而言,我假定dirname是目录名/路径的包装,因此不需要。
willdanceforfun

另外,如果dirname是一个大文件系统,则内存问题很明显。在我的文件只有1毫米的情况下,应用在memory_limit上需要512M内存。
abkrim

1
如果你需要一个像完整路径/home/examples/banana.jpg使用$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,而该PHP 4无法访问DirectoryIterator。
Joseph Callaars 2014年

1
为什么是“。” === $ file?这不是Java。
Dave Heq

2
Dave ...不,它与圆点匹配,如果在PHP中不匹配,则不会继续。搜索==和===之间的差异。
JSG

22

使用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/zh/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 2011年

@NexusRex:您也不应该从数据库中读取10,000条记录,但是就问题而言,这超出了范围
bcosca 2011年

同意!如果从数据库中读取,则可以使用“ limit”分页-当目录中有500万个XML文件要进行迭代时,运气就不那么好了。
NexusRex 2011年

有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);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.