PHP 5 で Iterators を効果的に使用する方法を理解しようとしていますが、ネット上に適切な例がたくさんないため、少し難しいことがわかりました。
ディレクトリをループして、その中のすべての (php) ファイルを読み取って、定義されたクラスを検索しようとしています。次にやりたいことは、クラス名をキーとして、ファイル パスを値として返す連想配列を作成することです。
RecursiveDirectoryIterator() を使用することで、ディレクトリを再帰的に処理できます。これを RecursiveIteratorIterator に渡すことで、ディレクトリの内容を 1 次元イテレータとして取得できます。次に、これにフィルターを使用することで、すべてのディレクトリと、考慮したいファイルだけを残す非phpファイルをフィルターで除外できます。
私が今やりたいことは、この反復子を別の反復子に渡すことができるようにすることです (どちらが適切かはわかりません)。これにより、各エントリをループするときに、マスター配列に結合する必要がある配列を取得できます。
説明が少し複雑なので、コード例を次に示します。
// $php_files now represents an array of SplFileInfo objects representing files under $dir that match our criteria
$php_files = new PhpFileFilter(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)));
class ClassDetector extends FilterIterator {
public function accept() {
$file = $this->current(); // get the current item, which will be an SplFileInfo object
// Match all the classes contained within this file
if (preg_match($regex, $file->getContents(), $match)) {
// Return an assoc array of all the classes matched, the class name as key and the filepath as value
return array(
'class1' => $file->getFilename(),
'class2' => $file->getFilename(),
'class3' => $file->getFilename(),
);
}
}
}
foreach (new ClassDetector($php_files) as $class => $file) {
print "{$class} => {$file}\n";
}
// Expected output:
// class1 => /foo.php
// class2 => /foo.php
// class3 => /foo.php
// class4 => /bar.php
// class5 => /bar.php
// ... etc ...
この例からわかるように、私は FilterIterator の accept() メソッドをハイジャックしています。これは私が知っている完全に間違った使用法ですが、1 つの関数を呼び出す方法を示すための例としてのみ使用しています。 、マスター配列にマージされた配列を返すようにします。
現時点では、RecursionIterator の 1 つを使用する必要があると考えていますが、これは RecursionIterator の機能のように思われるためですが、2 つの異なるメソッド (hasChildren() と getChildren() を使用するという考えは好きではありません) )) 目標を達成する。
要するに、オブジェクトの 1 次元配列 (?) を渡すために使用 (または拡張) できる Iterator を特定し、結果の配列をマスター配列に結合してそれを返すようにしようとしています。 .
これには他にもいくつかの方法があることに気づきました。たとえば、次のようなものです。
$master = array();
foreach($php_files as $file) {
if (preg_match($regex, $file->getContents(), $match)) {
// create $match_results
$master = array_merge($master, $match_results);
}
}
しかし、これはイテレータを使用する目的に反しており、ソリューションとしてもあまりエレガントではありません。
とにかく、私はそれを十分に説明したことを願っています。ここまで読んでくれてありがとう、そして事前に答えてくれてありがとう:)