Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8664861
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 12, 20262026-06-12T17:20:31+00:00 2026-06-12T17:20:31+00:00

I have created a custom iterator that extends RecursiveIteratorIterator which I use to iterate

  • 0

I have created a custom iterator that extends RecursiveIteratorIterator which I use to iterate over a Doctrine_Collection from a table that uses the NestedSet behavior (e.g., so that I apply custom sorting to records at each level in the hierarchy).

There are a couple of models in my project that leverage this iterator, so I have created a base class that looks like the following:

/** Base functionality for iterators designed to iterate over nested set
 *    structures.
 */
abstract class BaseHierarchyIterator
  extends RecursiveIteratorIterator
{
  /** Returns the component name that the iterator is designed to work with.
   *
   * @return string
   */
  abstract public function getComponentName(  );

  /** Inits the class instance.
   *
   * @param $objects  Doctrine_Collection Assumed to already be sorted by `lft`.
   *
   * @throws LogicException If $objects is a collection from the wrong table.
   */
  public function __construct( Doctrine_Collection $objects )
  {
    /** @kludge Initialization will fail horribly if we invoke a subclass method
     *    before we have initialized the inner iterator.
     */
    parent::__construct(new RecursiveArrayIterator(array()));

    /* Make sure we have the correct collection type. */
    $component = $this->getComponentName();
    if( $objects->getTable()->getComponentName() != $component )
    {
      throw new LogicException(sprintf(
        '%s can only iterate over %s collections.'
          , get_class($this)
          , $component
      ));
    }

    /* Build the array for the inner iterator. */
    $top = array();
    /** @var $object Doctrine_Record|Doctrine_Node_NestedSet */
    foreach( $objects as $object )
    {
      // ... magic happens here ...
    }

    parent::__construct(
        new RecursiveArrayIterator($top)
      , RecursiveIteratorIterator::SELF_FIRST
    );
  }

  ...
}

A subclass might look something like this:

/** Iterates hierarchically through a collection of User objects.
 */
class UserHierarchyIterator
  extends BaseHierarchyIterator
{
  /** Returns the component name that the iterator is designed to work with.
   *
   * @return string
   */
  public function getComponentName()
  {
    return UserTable::getInstance()->getComponentName();
  }

  ...
}

Note the @kludge at the top of the constructor in the base class:

/** @kludge Initialization will fail horribly if we invoke a subclass method
 *    before we have initialized the inner iterator.
 */
parent::__construct(new RecursiveArrayIterator(array()));

As long as I keep that extra initialization line at the top of the base class’ constructor, everything works as expected.

However, if I remove/comment that line, I get the following error as soon as script execution gets to $component = $this->getComponentName():

Fatal error: BaseHierarchyIterator::__construct(): The UserHierarchyIterator instance wasn’t initialized properly in /path/to/BaseHierarchyIterator.class.php on line 21.

Alternatively, if I remove the code that calls $this->getComponentName() (and the subsequent conditional block), the constructor still operates as expected (minus the check to make sure the component name is correct).

What is the root cause of this error? Is there a better workaround for this issue?

PHP version info:

PHP 5.3.3 (cli) (built: Jul  3 2012 16:40:30) 
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
    with Suhosin v0.9.29, Copyright (c) 2007, by SektionEins GmbH
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-12T17:20:32+00:00Added an answer on June 12, 2026 at 5:20 pm

    Fatal error: BaseHierarchyIterator::__construct(): The UserHierarchyIterator instance wasn’t initialized properly in /path/to/BaseHierarchyIterator.class.php on line 21.

    What is the root cause of this error?

    Your class extends from RecursiveIteratorIterator. To have an object of this type or a subtype thereof working, PHP needs to have it initialized properly before you call any other method or access a property of it. Properly means here that it’s parent constructor has been called, the initialization is done then.

    But you call a method before initialization (RecursiveIteratorIterator::__construct() has not been called yet). The method call in your case is:

    $this->getComponentName();
    

    You also have realized that so far. If you initialize before that call, you don’t have this fatal error. In your case the initialization is:

    parent::__construct(new RecursiveArrayIterator(array()));
    

    The strict check by PHP reserves PHP to do some special kind of recursive iterators that can delegate better to underlying data-structures. Recursive traversal is just a bit more complex as well, needs initialization of a stack and such which is all hidden by PHP. So that check is also done for safety reasons.

    If you compare that with IteratorIterator, you see that such a fatal error does not exists.

    Is there a better workaround for this issue?

    I won’t call it a workround. You actually implemented something similar comparable for what IteratorAggregate is for. But you just did too much at once, see your constructor, it is doing too much. This is a Flaw: Constructor does Real Work.

    So this calls for a cleaner separation of concerns and actually a more basic understanding of iterators could be helpful, too.

    The solution is rather straight forward: The only thing you need to do here is to move the data-handling logic from the constructor into an implementation of IteratorAggregate:

    abstract class BaseHierarchyIterator implements IteratorAggregate
    {
        private $objects;
    
        abstract public function getComponentName();
    
        public function __construct(Doctrine_Collection $objects) {
            $this->setObjects($objects);
        }
    
        public function getIterator() {
    
            /* Build the array for the inner iterator. */
            $top = array();
            /** @var $object Doctrine_Record|Doctrine_Node_NestedSet */
            foreach ($this->objects as $object) {
                // ... magic happens here ...
            }
    
            return new RecursiveArrayIterator($top);
        }
    
        private function setObjects($objects) {
    
            /* Make sure we have the correct collection type. */
            $component = $this->getComponentName();
    
            if ($objects->getTable()->getComponentName() != $component) {
                throw new LogicException(sprintf(
                    '%s can only iterate over %s collections.'
                    , get_class($this)
                    , $component
                ));
            }
    
            $this->objects = $objects;
        }
    }
    

    You then can just do recursive Iteration straight away:

    $users = new UserHierarchyIterator($objects);
    $it    = new RecursiveIteratorIterator(
                     $users, RecursiveIteratorIterator::SELF_FIRST
                 );
    

    As you can see, the only thing you need to solve your concrete problem is to separate the concerns a bit more. This will help you anyway, so you should be fine with it in the first run:

    [Iterator]  ---- performs traversal --->  [Container]
    

    The container has an interface the iterator can work on now. This by the way is exactly what an iterator object is. You actually used it wrong. If you follow that trail and as it’s common with IteratorAggregate, you can go from there to a true own iterator interface for your containers. Right now you iterate over the doctrine collection before you create the iterator object.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have created custom validator that validates object comparing its fields (it uses EntityManager
I have created a custom UIView that I would like to use on multiple
I have created custom drawable marker which uses canvas to draw bounds. Everything works
I have created custom cell in which there are n number of image views.
I have created a custom cell for loading into a table. The interface is
I have created a custom method that will return unique items, together with the
I have created a custom scroll. In which I am shifting the contents right
Have created a custom navigation menu in wordpress that has some pages and some
I have created custom listview in that have list of textview & list of
I have created Custom Dialog for my application. While i run that application in

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.