我正在尝试遍历包含大量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类'在第二个源代码文件中定义,因此返回的数组再次从索引0开始.这在RecursiveIteratorIterator中保留,因为每组结果代表一个单独的迭代器(因此键/值对).
无论如何,我现在要做的是找到组合这些的最佳方法,这样当我迭代新的迭代器时,我可以得到键是类名(来自$defined_classes
迭代器),值是原始文件路径,ala:
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()方法当前的iterator()值.但我不赞成这个解决方案,因为:
这听起来很复杂(这意味着代码看起来很可怕而且不直观
业务规则在类中是硬编码的,而我想定义一些通用的迭代器,并能够以这种方式组合它们以产生所需的结果.
任何想法或建议感激不尽.
我也意识到有更快,更有效的方法可以做到这一点,但这也是我自己使用迭代器的一种练习,也是一种促进代码重用的练习,因此任何必须编写的新迭代器应该尽可能小并尝试利用现有功能.
谢谢