【问题标题】:PHP Recursive Directory Iterator - ignore certain files.PHP 递归目录迭代器 - 忽略某些文件。
【发布时间】:2013-08-18 16:50:16
【问题描述】:

我有一个递归目录迭代器来从目录中选择文件。 SKIP_DOTS 允许我忽略“。”和 '..' 元素,但我也希望能够忽略 '__MACOSX' 目录和其他隐藏文件,例如 '.cache.php'

$iterator = new RecursiveDirectoryIterator($directory);
$iterator->setFlags(RecursiveDirectoryIterator::SKIP_DOTS);
$all_files  = new RecursiveIteratorIterator($iterator); 

还有其他答案 here 和 here 但只是想知道是否有更清洁的方法?

我希望PHP Manual - FilesystemIterator SetFlags 中会有一些东西,但似乎没有。

【问题讨论】:

  • 你为什么希望有内置的东西?有特殊要求的时候,指望别人写几行代码是不是很不合理?在 Windows 系统中,您经常会看到特殊的 desktop.ini 和 Thumbs.db 文件,它们是否也应该有一个特殊的标志?
  • @Jon 我明白你的意思,但如果不是为了帮助常见用例,为什么还要包含“RecursiveDirectoryIterator::SKIP_DOTS”?
  • @Kiksy:处理点条目的幼稚程序会立即进入无限递归,所以几乎每个人都想过滤掉它们。更不用说点是适用于 PHP 运行的所有平台上支持的几乎所有文件系统的约定。

标签: php iterator


【解决方案1】:

要过滤其他项目,您可以使用RecursiveCallbackFilterIterator。这 很好,因为使用过滤器的文件夹,整个子路径都会被修剪。 以下是过滤文件和子文件夹的示例:

<?php

$f_filter = function ($o_info) {
   $s_file = $o_info->getFilename();
   if ($s_file == '.git') {
      return false;
   }
   if ($s_file == 'readme.md') {
      return false;
   }
   return true;
};

$o_dir = new RecursiveDirectoryIterator('.');
$o_filter = new RecursiveCallbackFilterIterator($o_dir, $f_filter);
$o_iter = new RecursiveIteratorIterator($o_filter);

foreach ($o_iter as $o_info) {
   echo $o_info->getPathname(), "\n";
}

https://php.net/class.recursivecallbackfilteriterator

【讨论】:

    【解决方案2】:

    感谢@Sven 和 PHP 文档:

    $iterator = new RecursiveDirectoryIterator($directory);
    $iterator->setFlags(RecursiveDirectoryIterator::SKIP_DOTS);
    
    $filter = new MyRecursiveFilterIterator($iterator);
    
    $all_files  = new RecursiveIteratorIterator($filter,RecursiveIteratorIterator::SELF_FIRST);
    

    然后扩展RecursiveFilterIterator

    class MyRecursiveFilterIterator extends RecursiveFilterIterator {
    
        public static $FILTERS = array(
            '__MACOSX',
        );
    
        public function accept() {
            return !in_array(
                $this->current()->getFilename(),
                self::$FILTERS,
                true
            );
        }
    
    }
    

    根据评论In the PHP Manual

    【讨论】:

    • 这取决于 RecursiveDirectoryIterator 设置的标志,这里的代码期望 parent::current() 返回一个 SplFileInfo 对象 - 但它也可以是一个字符串。作为替代方案,可以使用RecursiveDirectoryIterator 本身并使用$this-&gt;getBasename()(过滤器装饰)或$this-&gt;getFilename()。只是添加。在构造函数中注意只接受RecursiveDirectoryIterator 作为$iterator 也很有帮助。我在 linux 隐藏文件的 gist 中放置了一些代码:HiddenFilesAndFolderFilterIterator.php
    【解决方案3】:

    在 RecursiveIteratorIterator 和 RecursiveDirectoryIterator 之间添加一个过滤器层:创建一个 RecursiveFilterIterator 并编写 accept() 函数,如果您希望元素出现在结果中,该函数将返回 true。将目录迭代器放入过滤器迭代器,将过滤器迭代器放入RecursiveIteratorIterator。迭代。

    对于“__MACOSX”目录等特殊情况,没有预定义的 SKIP 常量。

    【讨论】:

      猜你喜欢
      • 2013-12-01
      • 2011-01-03
      • 2012-11-06
      • 1970-01-01
      • 1970-01-01
      • 2010-12-19
      • 2022-01-25
      • 2019-09-12
      相关资源
      最近更新 更多