大量の PHP ファイルを含むディレクトリを反復処理し、各ファイルで定義されているクラスを検出しようとしています。
次の点を考慮してください。
$php_files_and_content = new PhpFileAndContentIterator($dir);
foreach($php_files_and_content as $filepath => $sourceCode) {
// echo $filepath, $sourceCode
}
上記の$php_files_and_content
変数は、キーがファイル パスであり、内容がファイルのソース コードであるイテレータを表します (例から明らかではなかったかのように)。
これは、ソース コードで定義されているすべてのクラスに一致する別のイテレータ ala に提供されます。
class DefinedClassDetector extends FilterIterator implements RecursiveIterator {
public function accept() {
return $this->hasChildren();
}
public function hasChildren() {
$classes = getDefinedClasses($this->current());
return !empty($classes);
}
public function getChildren() {
return new RecursiveArrayIterator(getDefinedClasses($this->current()));
}
}
$defined_classes = new RecursiveIteratorIterator(new DefinedClassDetector($php_files_and_content));
foreach($defined_classes as $index => $class) {
// print "$index => $class"; outputs:
// 0 => Class A
// 1 => Class B
// 0 => Class C
}
が数値的に連続していない理由$index
は、'クラス C' が 2 番目のソース コード ファイルで定義されているためです。したがって、返される配列は再びインデックス 0 から始まります。これは RecursiveIteratorIterator に保持されます。これは、結果の各セットが個別の Iterator (したがって、キーと値のペア) を表すためです。
とにかく、私が今やろうとしているのは、これらを組み合わせる最良の方法を見つけることです。新しいイテレータを反復処理するときに、キーが ($defined_classes
イテレータからの) クラス名であり、値が元のファイル パスであることがわかります。 、あら:
foreach($classes_and_paths as $filepath => $class) {
// print "$class => $filepath"; outputs
// Class A => file1.php
// Class B => file1.php
// Class C => file2.php
}
そして、それが私がこれまで立ち往生しているところです。
現時点で考えられる唯一の解決策は、新しい RecursiveIterator を作成することです。これは current() メソッドをオーバーライドして外側のイテレータ key() (元のファイルパス) を返し、key() メソッドを返して返します。現在の iterator() 値。しかし、次の理由から、私はこのソリューションを支持していません。
- 複雑に聞こえます (つまり、コードが見苦しく、直感的ではないということです)。
- ビジネス ルールはクラス内にハードコーディングされていますが、私はいくつかのジェネリック イテレータを定義し、それらを組み合わせて必要な結果を生成できるようにしたいと考えています。
アイデアや提案はありがたく受け取りました。
これを行うためのはるかに高速で効率的な方法があることも認識していますが、これは自分自身のためにイテレーターを使用する練習でもあり、コードの再利用を促進する練習でもあります。したがって、作成する必要がある新しいイテレーターはできるだけ最小限に抑える必要があります。既存の機能を活用してみてください。
ありがとう