Я пытаюсь понять, как эффективно использовать итераторы в 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, что, как я знаю, является совершенно неправильным использованием, но я использую его только в качестве примера, чтобы продемонстрировать, как я просто хочу, чтобы вызывалась одна функция. , и чтобы он возвращал массив, объединенный в главный массив.
На данный момент я думаю, что мне придется использовать один из RecursionIterators, поскольку это похоже на то, что они делают, но мне не нравится идея использования двух разных методов (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);
}
}
но это противоречит цели использования итераторов и не очень элегантно как решение.
В любом случае, я надеюсь, что объяснил это достаточно хорошо. Спасибо, что дочитали до этого места и заранее ответили :)