Вложенные RecursiveIteraotrs
Я хочу перебирать вложенные объекты, используя интерфейс RecursiveIterator. У объекта HeadHunterEntity может быть много CandidateEntities. Я хочу перебрать все CandidateEntities в основном цикле, но что-то не так.
У меня есть основной цикл, как это:
$iterator = new RecursiveIteratorIterator(new RecursiveHunterCandidatesIterator(new RecursiveArrayIterator($this->getHeadHunters())));
foreach ($iterator as $object) {
echo('<br>MAIN LOOP: ' . (is_object($object) ? get_class($object) : $object));
}
RecursiveHunterCandidatesIterator
class RecursiveHunterCandidatesIterator extends RecursiveFilterIterator {
public function accept() {
echo "<br>RecursiveHunterCandidatesIterator (accept) hasChildren: " . $this->hasChildren();
return $this->hasChildren();
}
public function hasChildren() {
$current = $this->current();
echo "<br>RecursiveHunterCandidatesIterator (hasChildren) current Class: " . get_class($current);
return is_object($this->current()) ? (boolean)count($this->current()->getHuntedCandidates()) : FALSE;
}
public function getChildren() {
echo "<br>RecursiveHunterCandidatesIterator (getChildren) count: " . count($this->current()->getHuntedCandidates());
$childIterator = new RecursiveArrayIterator($this->current()->getHuntedCandidates());
$childIterator2 = new RecursiveArrayIterator(array(1,2,3));
return $childIterator;
}
}
Результат неожиданный, у меня ничего нет в основном цикле:(
RecursiveHunterCandidatesIterator (hasChildren) current Class: HeadHunterEntity
RecursiveHunterCandidatesIterator (accept) hasChildren: 1
RecursiveHunterCandidatesIterator (hasChildren) current Class: HeadHunterEntity
RecursiveHunterCandidatesIterator (hasChildren) current Class: HeadHunterEntity
RecursiveHunterCandidatesIterator (getChildren) count: 2
RecursiveHunterCandidatesIterator (hasChildren) current Class: HeadHunterEntity
RecursiveHunterCandidatesIterator (accept) hasChildren:
RecursiveHunterCandidatesIterator (hasChildren) current Class: HeadHunterEntity
RecursiveHunterCandidatesIterator (hasChildren) current Class: HeadHunterEntity
RecursiveHunterCandidatesIterator (accept) hasChildren:
RecursiveHunterCandidatesIterator (hasChildren) current Class: HeadHunterEntity
Но если вместо этого я верну $childIterator2, в основном цикле будут результаты, как и ожидалось:
RecursiveHunterCandidatesIterator (hasChildren) current Class: HeadHunterEntity
RecursiveHunterCandidatesIterator (accept) hasChildren: 1
RecursiveHunterCandidatesIterator (hasChildren) current Class: HeadHunterEntity
RecursiveHunterCandidatesIterator (hasChildren) current Class: HeadHunterEntity
RecursiveHunterCandidatesIterator (getChildren) count: 2
MAIN LOOP: 1
MAIN LOOP: 2
MAIN LOOP: 3
RecursiveHunterCandidatesIterator (hasChildren) current Class: HeadHunterEntity
RecursiveHunterCandidatesIterator (accept) hasChildren:
RecursiveHunterCandidatesIterator (hasChildren) current Class: HeadHunterEntity
RecursiveHunterCandidatesIterator (hasChildren) current Class: HeadHunterEntity
RecursiveHunterCandidatesIterator (accept) hasChildren:
RecursiveHunterCandidatesIterator (hasChildren) current Class: HeadHunterEntity
$ this-> current () -> getHuntedCandidates () возвращает массив, поэтому он должен быть в основном цикле, как поддельные 1,2,3 aray в $childIterator2...
Что я делаю не так?
1 ответ
Я нашел решение. Так как метод getChildren() RecursiveIterator должен возвращать экземпляр RecursiveIterator, я расширил RecursiveArrayIterator (Вы также можете расширить RecursiveFilterIterator, если вам нужно фильтровать объекты на этом уровне).
class CandidateIterator extends RecursiveArrayIterator {
public function hasChildren() {
return false;
}
}
и, конечно, изменение вернуло итератор в классе RecursiveHunterCandidatesIterator:
class RecursiveHunterCandidatesIterator extends RecursiveFilterIterator {
(..)
public function getChildren() {
$childIterator = new CandidateIterator(new RecursiveArrayIterator($this->current()->getHuntedCandidates()));
return $childIterator;
}
}