【问题标题】:PHP script to loop through all of the files in a directory?PHP脚本循环遍历目录中的所有文件?
【发布时间】:2010-11-17 06:58:56
【问题描述】:

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

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

【问题讨论】:

标签: php file


【解决方案1】:

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

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

【讨论】:

  • 注意:许多服务器没有安装 SPL,因此您将无法使用 DirectoryIterator 类(请参阅下面我的替代帖子)。如果可以,请使用它!
  • 注意[2]:确保您了解上面的dirname() 函数将获取您放置在那里的任何路径的父文件夹。就我而言,我假设 dirname 是目录名称/路径的包装器,因此不需要它。
  • 另外,如果 dirname 它是一个大文件系统,那么内存问题就很明显了。在我有 1 百万个文件的情况下,应用程序在 memory_limit 上需要 ~512M 内存。
  • 如果你需要像/home/examples/banana.jpg这样的完整路径,请使用$fileinfo-&gt;getPathname()
  • 你可以使用 !$fileinfo->isDir() 来避免对目录的操作
【解决方案2】:

如果您无权访问 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);
}
?>

【讨论】:

  • 你能说出你无法访问它的情况吗?
  • 很多遗留应用程序使用 PHP 4,它无法访问 DirectoryIterator。
  • 为什么是'.' === $文件?这不是 Java。
  • Dave... 不,它与点匹配,如果在 PHP 中不匹配,则不会继续。搜索 == 和 === 之间的区别。
【解决方案3】:

使用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);
?>

【讨论】:

    【解决方案4】:

    您也可以使用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";
      }
      

      【讨论】:

        【解决方案6】:

        glob() 具有排序和模式匹配的规定。因为返回值是一个数组,所以你可以做大部分你需要的事情。

        【讨论】:

        • 这很好,除非您要处理大量文件... > 10,000。你会用完内存。
        • @NexusRex:您也不应该从数据库中读取 10,000 条记录,但就问题而言,这超出了范围
        • 同意!如果从数据库中读取,您可以使用“limit”进行分页——当您有一个包含 500 万个 XML 文件的目录要迭代时,就没有这样的运气了。
        • 有 SPL GlobIterator。
        • 这对于正确使用来说太棒了。就我而言,我想每天晚上为一个小型公司网站清除下载文件夹。我希望能够在下载文件夹中有子目录,这是我正在寻找的解决方案。感谢发帖!
        【解决方案7】:

        我想大多数时候你想跳过...。这是与 递归:

        <?php
        
        $rdi = new RecursiveDirectoryIterator('.', FilesystemIterator::SKIP_DOTS);
        $rii = new RecursiveIteratorIterator($rdi);
        
        foreach ($rii as $di) {
           echo $di->getFilename(), "\n";
        }
        

        https://php.net/class.recursivedirectoryiterator

        【讨论】:

          【解决方案8】:

          为了完整起见(因为这似乎是一个高流量的页面),我们不要忘记过去的好dir() function

          $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);
          

          【讨论】:

            【解决方案9】:

            你也可以这样做

            $path = "/public";
            
            $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
            
            foreach ($objects as $name => $object) {
              if ('.' === $object) continue;
              if ('..' === $object) continue;
            
            str_replace('/public/', '/', $object->getPathname());
            
            // for example : /public/admin/image.png => /admin/image.png
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-01-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-07-05
              • 1970-01-01
              相关资源
              最近更新 更多