Вложенные 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;
    }
}
Другие вопросы по тегам