Я пытаюсь понять, как эффективно использовать итераторы в PHP 5, и без большого количества достойных примеров в сети это будет немного сложно.
Я пытаюсь перебрать каталог и прочитать все файлы (php) внутри, чтобы найти определенные классы. Затем я хочу получить ассоциативный массив с именами классов в качестве ключей, а пути к файлам в качестве значений.
Используя RecursiveDirectoryIterator (), я могу проходить через каталоги.
Передав это в RecursiveIteratorIterator, я могу получить содержимое каталога как одномерный итератор.
Затем, используя фильтр, я могу отфильтровать все каталоги и не-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 ...
Как вы можете видеть из этого примера, я как бы угоняю метод accept () для FilterIterator, что, как я знаю, является совершенно некорректным использованием, но я использую его только в качестве примера, чтобы продемонстрировать, как я просто хочу одну функцию быть вызванным и для него вернуть массив, который объединен в основной массив.
В данный момент я думаю, что мне придется использовать один из RecursionIterator, поскольку, похоже, это то, что они делают, но мне не нравится идея использовать два разных метода (hasChildren () и getChildren ()) для достижения цели.
Короче говоря, я пытаюсь определить, какой итератор я могу использовать (или расширить), чтобы заставить его проходить по одномерному массиву (?) Объектов, и заставить его объединить полученный массив в основной. и верни это.
Я понимаю, что есть несколько других способов обойти это, аля что-то вроде:
$master = array();
foreach($php_files as $file) {
if (preg_match($regex, $file->getContents(), $match)) {
// create $match_results
$master = array_merge($master, $match_results);
}
}
но это отрицательно сказывается на цели использования итераторов и не очень элегантно в качестве решения.
В любом случае, я надеюсь, что объяснил это достаточно хорошо. Спасибо, что прочитали это далеко, и за ваши ответы заранее:)