6

setInfoClass次のメソッドを使用して、カスタムクラスをイテレータに設定しようとしています。

このメソッドを使用して、getFileInfoおよびgetPathInfoが呼び出されたときに使用されるカスタムクラスを設定します。このメソッドに渡されるクラス名は、SplFileInfoから派生している必要があります。

私のクラスは次のようなものです(簡略化した例):

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

イテレータコードは次のとおりです。

$rit = new RecursiveIteratorIterator(
           new RecursiveDirectoryIterator('/some/file/path/'),
           RecursiveIteratorIterator::SELF_FIRST);

はオブジェクトもRecursiveDirectoryIterator継承するため、メソッドを提供します。マニュアルには記載されていませんが、リフレクションはそこにあることを示しています。DirectoryIteratorSplFileInfosetInfoClass

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

ここまではすべて問題ありませんが、ディレクトリを反復処理する場合は

$rit->getInnerIterator()->setInfoClass('MyFileInfo');
foreach($rit as $file) {
    var_dump( $file );
}

次の奇妙な結果が得られます

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

MyFileInfoそのため、ピックアップされている間は、そのプロパティにアクセスできません。カスタムメソッドを追加すると、それらを正常に呼び出すことができますが、プロパティは不明です。

infoクラスをイテレータに設定せずにSplFileInfoオブジェクト(マニュアルの例に示されているように)に設定すると、同じUNKNOWN結果が得られます。

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

しかし、私がやるとそれは動作します

foreach($rit as $file) {
    $file = new MyFileInfo($file);
    var_dump( $file );
}

残念ながら、これを使用したいコードはやや複雑で、さらにいくつかのイテレーターをスタックします。このようにMyFileInfoクラスを作成することはオプションではありません。

それで、これを機能させる方法や、PHPがこれを奇妙に動作させる理由を誰かが知っていますか?

ありがとう。

4

1 に答える 1

2

正確な理由はわかりませんが、動作します

class MyFileInfo extends SplFileInfo
{
  public $props;

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

    parent::__construct($filename);
  }
}
于 2010-04-03T21:37:50.863 に答える