views:

51

answers:

2

I have a complex hierarchy of nested objects, with all of the child objects (stored an array of objects in the parent class) containing a property linking back to their parent: fairly simple and straightforward, with no real problems. If I do a var_dump of any object in the hierarchy, I'll get a recursive reference in the dump, exactly as I'd expect.

FIRSTGEN 
   _children array of objects of type SECONDGEN
      SECONDGEN #1
         _parent object of type FIRSTGEN
         _children array of objects of type THIRDGEN
            THIRDGEN #1
               _parent object of type SECONDGEN
            THIRDGEN #2
               _parent object of type SECONDGEN
      SECONDGEN #2
         _parent object of type FIRSTGEN
         _children array of objects of type THIRDGEN
            THIRDGEN #3
               _parent object of type SECONDGEN

I've recently added some new elements to that hierarchy, and they don't follow quite the same pattern. They are stored in an array of objects in the top-level parent, but contain a property linking them back, not to their parent, but to a sibling. When I do a var_dump now, I get a "Fatal error: Nesting level too deep - recursive dependency?".

FIRSTGEN 
   _children_1 array of objects of type SECONDGEN_1
      SECONDGEN_1 #1
         _parent object of type FIRSTGEN
         _children array of objects of type THIRDGEN
            THIRDGEN #1
               _parent object of type SECONDGEN_1
            THIRDGEN #2
               _parent object of type SECONDGEN_1
      SECONDGEN_1 #2
         _parent object of type FIRSTGEN
         _children array of objects of type THIRDGEN
            THIRDGEN #3
               _parent object of type SECONDGEN_1
   _children_2 array of objects of type SECONDGEN_2
      SECONDGEN_2 #1
         _parent object of type SECONDGEN_1

Everything else within the code works correctly, with the exception of that var_dump(). I've tried creating a simpler example to demonstrate the problem, so that I could provide an example when asking this question; but haven't been able to replicate it in a short test, only within my more complex code.

I know that the solution is to refactor the relationship so that my _children_2 array of SECONDGEN_2 objects is held in the appropriate SECONDGEN_1 parent, making the parent relationship "correct"... I've already started doing this. However, I'm intrigued by the error, and wondered if anybody else had encountered it (and how you dealt with it yourself).

+2  A: 

Sometimes (but seldom, as there are limited valid used for such contrustcs) this happens, and as long as your code works properly, I wouldn't give it much thought that a var_dump (a debugging tool, not a production one) cannot cope with it. However, if you still need var_dump to work, I can heartily recommend running xdebug, in which you can set max-depth the var_dump will show, the max-length of a string dump and the maximum amount of children.

Wrikken
I think this is one of those cases where there's my reason for the sibling relationship (to provide a method to list all SECONDGEN_2 children directly from the FIRSTGEN parent) can be done as easily by attaching SECONDGEN_2 children to their corresponding SECONDGEN_1 object, and for the FIRSTGEN method to loop through the SECONDGEN_1 objects calling a listSECONDGEN_2 method there and merging the lists; so not really a valid use. So I'm reworking it anyway.
Mark Baker
I'm having a hard time visualizing the actual structure of references, but it could always be that in a sufficient sample, there is a path for PHP to hop nodes without encountering the same node before it's maximum nesting level. How many nodes do you have, and is there such a path?
Wrikken
+1  A: 

Looks like a PHP limitation in self-referencing code and trying to display it with print_r, var_dump, var_export, or search through it with in_array. Basically there's no way for those functions to know where to stop recursing if an object is referenced cirularly.

According to this bug report the easiest way to reproduce this is:

$outText = var_export( $GLOBALS, true );
print_r($outText) ;

Other bug reports mention it too, with some more test cases. I'd say that if this is only triggered in var_dump you shouldn't worry too much about it. I definitely second Wrikken's suggestion about xdebug if this is for debugging purposes.

Fanis
The second bug report that you mention is a simple parent->child->parent recursion, which doesn't cause var_dump() any problems... it simply reports the recursion. It doesn't even cause issues with parent->child->grandchild->parent recursion. I was surprised at the sibling case though... from the successful handling of the more common types of recursion, I'd have expected the sibling relationship to be trapped in the same way.
Mark Baker