【问题标题】:How to use RecursiveDirectoryIterator with a Modified Date filter?如何使用带有修改日期过滤器的 RecursiveDirectoryIterator?
【发布时间】:2013-07-08 18:18:38
【问题描述】:

我正在尝试读取我们服务器上的所有文件(>2M 文件),并使用this example 取得了很大进展,使用正则表达式将其过滤为仅 PHP 和 HTML 文件。我的日子一直在尝试使用PHP Documentation 复制文件的修改或创建时间而不是文件名的过滤,但似乎找不到一种方法来传递我想要比较的日期。

这是我的工作起点:

abstract class FilesystemRegexFilter extends RecursiveRegexIterator {
    protected $regex;
    public function __construct(RecursiveIterator $it, $regex) {
        $this->regex = $regex;
        parent::__construct($it, $regex);
    }
}
class FilenameFilter extends FilesystemRegexFilter {
    public function accept() {
        return ( ! $this->isFile() || preg_match($this->regex, $this->getFilename()));
    }
}
class DirnameFilter extends FilesystemRegexFilter {
    public function accept() {
        return ( ! $this->isDir() || preg_match($this->regex, $this->getFilename()));
    }
}

$directory = new RecursiveDirectoryIterator("c:\\www");
$filter = new DirnameFilter($directory, '/^(?!cache)/');
$filter = new FilenameFilter($filter, '/\.(?:php|inc)$/');
foreach(new RecursiveIteratorIterator($filter) as $filename => $file) {
    echo $filename . PHP_EOL;
}

这是我试图通过复制/粘贴使用正则表达式的代码来完成的“伪代码”。

abstract class FilesystemDateFilter extends RecursiveSOMEKINDOFIterator {
    protected $earliest_date;
    public function __construct(RecursiveIterator $it, $earliest_date) {
        $this->earliest_date = $earliest_date;
        parent::__construct($it, $earliest_date);
    }
}
class FiledateFilter extends FilesystemDateFilter {
    // Filter files against the Earliest Date
    public function accept() {
        return ( ! $this->isFile() || $this->getMTime() >= $this->earliest_date );
    }
}

$filter = new FilenameFilter($filter, '/\.(?:php|inc)$/');
$filter = new FiledateFilter($filter, '2012-12-31');

问题是示例代码中只能使用有效的正则表达式,并且对于我尝试过的其他类,第二个参数不允许在其构造中使用。我似乎无法找出 RecursiveRegexIterator 的正确替代方法,这将允许我传递一个日期值来比较过滤器以包含在上周创建/修改的 PHP/HTML 文件中。

【问题讨论】:

  • 而不是将其塞进RecursiveRegexIterator,您是否考虑过只使用RecursiveFilterIterator
  • 你不需要传递给,parent::__construct($it, $earliest_date);所以你可以使用RecursiveFilterIterator
  • 很想这样做....对于整个迭代器这件事我是新手,我开始使用 Regex 过滤文件的示例。这节省了大量的处理时间,所以从我知道有效的代码开始学习曲线。我在 Google 上搜索了您的建议,但是当您尝试了解它的工作原理时,使用迭代器的“过滤器”“新”“文件”等术语并不能完全返回任何特定或可用的内容。
  • 试试class FiledateFilter extends RecursiveFilterIterator,声明一个public $earliestdate,然后设置它(不是在它的构造函数参数中,因为签名不应该改变)。看看情况如何......

标签: php regex directory


【解决方案1】:

好的,你可以试试这个例子:

class FilesystemDateFilter extends RecursiveFilterIterator 
{
  protected $earliest_date;

  public function __construct(RecursiveIterator $it, $earliest_date) 
  {
      $this->earliest_date = $earliest_date;
      parent::__construct($it);
  }

  public function accept() 
  {
      return ( ! $this->isFile() || $this->getMTime() >= $this->earliest_date );
  }

  public function getChildren() 
  {
      return new static ( $this->getInnerIterator ()->getChildren (), $this->earliest_date );
  }   
}

$directory = new RecursiveDirectoryIterator("c:\\www");
$filter = new FilesystemDateFilter($directory, strtotime('2012-12-31'));

foreach(new RecursiveIteratorIterator($filter) as $filename => $file) {
   echo $filename . PHP_EOL;
}

注意http://php.net/manual/en/directoryiterator.getmtime.php 返回时间戳,所以你也需要提供它。

您缺少的是覆盖getChildern,它将参数传递给子级。

【讨论】:

  • 天哪,你不想看到我想出的可怕的烂摊子来完成这件事。要过滤文件名,我是否可以立即执行“$filter = new FilenameFilter($filter, '/\.(?:php|inc)$/');”从原来的例子?我很快就会尝试它,只是想知道它是否可能,或者是否将其构建到您给出的示例中。
  • 不确定我是否理解您的问题,但您可以将它与您的示例一起使用,您的正则表达式搜索很好。
  • 我仍然坚持这一点:它们都引用 $this,它没有 getMTim​​e() - 如何从 accepti 函数访问 ->getMTim​​e()?
  • 我在接受函数中得到时间没有问题,因为它是 DirectoryIterator,只是它的时间戳,我已经更新了示例。
  • 唉,我使用的是 PHP 5.2。需要一些时间来设置 5.3 环境...不过谢谢。
猜你喜欢
  • 2018-01-07
  • 2018-06-03
  • 2016-01-13
  • 2021-04-11
  • 1970-01-01
  • 1970-01-01
  • 2020-07-21
  • 2017-05-26
  • 2020-03-27
相关资源
最近更新 更多