如何使用RecursiveIteratorIterator忽略目录? [英] How to ignore directories using RecursiveIteratorIterator?

查看:123
本文介绍了如何使用RecursiveIteratorIterator忽略目录?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经尝试了几种方法来在文件系统上使用 RecursiveIteratorIterator 忽略某些目录。

I have tried several methods to ignore certain directories using RecursiveIteratorIterator on a file system.

为了这个缘故例如,我想忽略以下目录: / cache

For the sake of an example say I want to ignore the following directory: /cache.

我的 Iterator 看起来像这样:

//$dirname is root
$directory = new RecursiveDirectoryIterator($dirname);
$mega = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST);

foreach ($mega as $fileinfo) {
 echo $fileinfo;
}

我已经能够使用忽略某些文件扩展名pathinfo 例如,这可行:

I have been able to ignore certain file extensions using pathinfo for example this works:

$filetypes = array("jpg", "png");
$filetype = pathinfo($fileinfo, PATHINFO_EXTENSION);

foreach ($mega as $fileinfo) {
    if (!in_array(strtolower($filetype), $filetypes)) {
    echo $fileinfo;
    }
}

当我尝试使用 PATHINFO_DIRNAME (使用数组中相应的目录路径)它不起作用,没有错误,它只是不会忽略目录。

When I try it using PATHINFO_DIRNAME (with the appropriate directory paths in the array) it does not work, there are no errors, it just does not ignore the directories.

我还尝试使用 FilterIterator 无效,现在我想也许我应该使用 RegexIterator

I have also experimented with using FilterIterator to no avail, and now I'm thinking maybe I should use RegexIterator.

使用 RecursiveIteratorIterator 忽略目录的最简单,最有效的方法是什么?

What would be the simplest and most efficient way to ignore directories using RecursiveIteratorIterator ?

无效的实验。
使用 PATHINFO_DIRNAME

$dirignore = array("cache", "cache2");
$directory = new RecursiveDirectoryIterator($dirname);
$mega = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST);
$dirtype = pathinfo($fileinfo, PATHINFO_DIRNAME); 

if (!in_array($dirtype), $dirignore)) {
echo $fileinfo;  //no worky still echo directories
}

使用 FilterIterator (不知道这是如何工作的)

Using FilterIterator (not sure how this works)

class DirFilter extends FilterIterator
{
    public function accept()
    {
        //return parent::current() != "..\cache\";

       $file = $this->getInnerIterator()->current();
       if ($file != "..\cache")
       return $file->getFilename();

      //also tried with same error as below
      //return !preg_match('/\cache', $file->getFilename());
    }
}

$directory= new RecursiveDirectoryIterator($dirname);
$directory = new DirFilter($directory); 
$mega = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST);
// loop

结果为错误:一个实例需要RecursiveIterator或IteratorAggregate创建它

推荐答案

您的 DirFilter 想扩展 RecursiveFilterIterator ,因为它与递归迭代器一起使用。不这样做是造成错误的原因。

Your DirFilter wants to extend RecursiveFilterIterator, since it is being used with a recursive iterator. Not doing that, is the cause of your error.

class DirFilter extends RecursiveFilterIterator
{
    // …
}

下一步是弄清楚如何使用正确地接受()。它应该返回 true false 值,该值指示是否应包含当前项目(<$ c迭代中$ c> true )或排除( false )。从 accept()返回文件名不是您想要做的。

The next step is figuring out how to use accept() properly. It is supposed to return a true or false value, which dictates whether the current item should be included (true) or excluded (false) from the iteration. Returning a file name from accept() is not what you want to be doing.

class DirFilter extends RecursiveFilterIterator
{
    public function accept()
    {
        $excludes = array("cache", "cache2");
        return !($this->isDir() && in_array($this->getFilename(), $excludes));
    }
}






能够传入排除目录数组可能会很好。这需要更多的代码,但更可重用。


It might be nice to be able to pass in the array of excluded directories. This requires a little more code but is much more reusable.

class DirFilter extends RecursiveFilterIterator
{
    protected $exclude;
    public function __construct($iterator, array $exclude)
    {
        parent::__construct($iterator);
        $this->exclude = $exclude;
    }
    public function accept()
    {
        return !($this->isDir() && in_array($this->getFilename(), $this->exclude));
    }
    public function getChildren()
    {
        return new DirFilter($this->getInnerIterator()->getChildren(), $this->exclude);
    }
}

此代码可以像:

$directory = new RecursiveDirectoryIterator($dirname);
$filtered = new DirFilter($directory, $dirignore); 
$mega = new RecursiveIteratorIterator($filtered, …);

这篇关于如何使用RecursiveIteratorIterator忽略目录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆