将自定义FileInfo类设置为Iterator的正确方法

Gor*_*don 6 php spl iterator

我试图通过以下setInfoClass方法将自定义类设置为迭代器:

使用此方法设置将在调用getFileInfo和getPathInfo时使用的自定义类.传递给此方法的类名必须从SplFileInfo派生.

我的班级是这样的(简化示例):

class MyFileInfo extends SplFileInfo
{
    public $props = array(
        'foo' => '1',
        'bar' => '2'
    );
}
Run Code Online (Sandbox Code Playgroud)

迭代器代码是这样的:

$rit = new RecursiveIteratorIterator(
           new RecursiveDirectoryIterator('/some/file/path/'),
           RecursiveIteratorIterator::SELF_FIRST);
Run Code Online (Sandbox Code Playgroud)

既然RecursiveDirectoryIterator是通过继承DirectoryIterator也是一个SplFileInfo对象,它提供了setInfoClass方法.它没有在手册中列出,但反射显示它在那里:

shell$ php --rc RecursiveDirectoryIterator
// ...
Method [ <internal:SPL, inherits SplFileInfo> public method setInfoClass ] {  
  - Parameters [1] {
    Parameter #0 [ <optional> $class_name ]
  }
}
Run Code Online (Sandbox Code Playgroud)

一切都很好,但是在迭代目录时

$rit->getInnerIterator()->setInfoClass('MyFileInfo');
foreach($rit as $file) {
    var_dump( $file );
}
Run Code Online (Sandbox Code Playgroud)

我得到以下奇怪的结果

object(MyFileInfo)#4 (3) {
  ["props"]=>UNKNOWN:0
  ["pathName":"SplFileInfo":private]=>string(49) "/some/file/path/someFile.txt"
  ["fileName":"SplFileInfo":private]=>string(25) "someFile.txt"
}
Run Code Online (Sandbox Code Playgroud)

因此,虽然MyFileInfo被拿起,我无法访问它的属性.如果我添加自定义方法,我可以调用它们,但任何属性都是UNKNOWN.

如果我没有将info类设置为迭代器,而是设置为SplFileInfo对象(如手册中的示例所示),它将提供相同的UNKNOWN结果:

foreach($rit as $file) {
    // $file is a SplFileInfo instance
    $file->setInfoClass('MyFileInfo');
    var_dump( $file->getFileInfo() );
}
Run Code Online (Sandbox Code Playgroud)

但是,当我这样做时它会起作用

foreach($rit as $file) {
    $file = new MyFileInfo($file);
    var_dump( $file );
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,我想要使用它的代码有点复杂,并且堆栈了更多的迭代器.像这样创建MyFileInfo类不是一个选项.

那么,有没有人知道如何使这个工作或为什么PHP表现这么奇怪?

谢谢.

Vol*_*erK 2

无法告诉你确切的原因,但它适用于

class MyFileInfo extends SplFileInfo
{
  public $props;

  public function __construct($filename) {
    $this->props = array(
      'foo' => '1',
      'bar' => '2'
    );

    parent::__construct($filename);
  }
}
Run Code Online (Sandbox Code Playgroud)