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