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
継承するため、メソッドを提供します。マニュアルには記載されていませんが、リフレクションはそこにあることを示しています。DirectoryIterator
SplFileInfo
setInfoClass
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がこれを奇妙に動作させる理由を誰かが知っていますか?
ありがとう。