PHP 5.2 – Nesting level too deep – recursive dependency?
13th November 2006
I installed PHP 5.2 on one of my testing servers today and a couple of bits of code that previously worked fine in version 5.1.6 threw fatal errors in the new version. The error message was “Nesting level too deep – recursive dependency?” and it took a little time to track down the root of the problem. Here’s what I’d done wrong.
In PHP there are two comparison operators, == and ===. It’s generally known that the first is not strict about type but the second is. So, for example
echo ( false == 0 ); // true
echo ( false === 0 ); // false
- 0 is an integer and false is a boolean
My problem arose from using non-strict typing with objects.
$a = new MyObj(); $b = new MyObj(); if( $a == $b ) ...
I hadn’t considered what I was doing with this code. When comparing two objects using the non-strict comparison operator (==) PHP compares all the properties of the objects and if they match the objects are deemed to be equal. If they don’t match they are not equal. In effect, we have a recursive comparison of all the properties of each object, and all their properties, etc. until we reach basic data types like strings and integers.
If, however, we use strict comparison (===), PHP will check whether the two objects are exactly the same object, not just objects with the same properties.
class MyObj
{
public $p;
}
$a = new MyObj();
$b = new MyObj();
$c = new MyObj();
$a->p = 1;
$b->p = 1;
$c->p = 2;
echo ( $a == $c ); // false
echo ( $a == $b ); // true
echo ( $a === $b ); // false
The problem arises if you have circular references in your objects properties. So, for example
class MyObj
{
public $p;
}
class OtherObj
{
public $q;
}
$a = new MyObj();
$b = new OtherObj();
$a->p = $b;
$b->q = $a; // the circular reference: $a->p->q === $a
$c = new MyObj();
$d = new OtherObj();
$c->p = $d;
$d->q = $c;// another circular reference: $c->p->q === $c
echo ( $a == $c ); // Fatal error:
Nesting level too deep - recursive dependency?
In order to compare $a to $c, PHP must compare their properties. So the logic in PHP goes something like this: $a == $c if $a->p == $c->p if $a->p->q == $c->p->q if $a->p->q->p == $c->p->q->p etc. indefinitely.
PHP 5.1 seemed to smooth over the problem somehow (probably after a certain level of recursion it simply returned false) – and usually it worked out fine. PHP 5.2 correctly produces the fatal error above.
Once you know the problem, the solution is easy – use strict comparison.
echo ( $a === $c ); // false (and no error)
The strict comparison will simply check whether the two objects are at the same location in memory and so doesn’t even look at the values of the properties.
N.B. The same problem can arise when using the negated comparison operators (use !== instead of !=) and when using in_array (use in_array‘s third parameter to indicate strict comparison).
Tags: PHP

18 Comments add your own
you saved my day. thanks man
greenone | 8th December 2006 at 05:31
Indeed, very helpfull tip, thanks
Willem | 15th December 2006 at 13:51
Thanks!!
nuxodin | 31st December 2006 at 19:49
Thanks for the tip. I went over the change log and the update info before upgrading to php 5.2 hoping to find breaking changes before upgrading.
This issue wasn’t mentioned anywhere.
Shahar | 1st January 2007 at 11:20
I have supplied Ilia with a distilled overview of your analysis to be added to the Upgrading guide with the next release. Thanks for this, and in the future do not hesitate to contact internals if you find stuff like this not being mentioned in the Upgrading guide.
Lukas | 1st January 2007 at 23:50
I upgraded my server late last night and didn’t realise it would cause any problems until clients rang the next morning saying their site was broken.
Thanks for posting your information, it saved me hours of troubleshooting!
Kenny | 1st February 2007 at 01:47
Just another thanks I was banging my head against a wall for an hour with problems caused by this stupid issue…
Keith | 6th March 2007 at 07:20
Thanks a lot
that bug had me stumped – and all I needed was a single extra character!
Nad | 14th March 2007 at 02:10
Indeed, +1 person who’s day you’ve saved
tolan | 21st March 2007 at 16:31
Thank you for the tip, saved me hours of possible debugging.
loconet | 6th April 2007 at 20:13
Big thanks for this. I hit the same problem with array_search and adding the strict parameter fixed it.
I didn’t really know what strict did before. Now that I do I’ll use it always – it’s got to be faster than comparing all the properties.
Rick Mason | 9th May 2007 at 20:41
Very useful, thanks. (I was wondering how such a bug could have stayed unknown, I’m glad to know it’s simply because of upgrading PHP.)
a3_nm | 19th June 2007 at 10:49
Indeed,Thank you for the tip
michael | 29th June 2007 at 17:32
this error also occurs with the Get_Browser() function as well as some PREG functions.
Chris | 9th July 2007 at 14:19
Thanks a lot! Like you, I just upgraded my PHP and began to get this error. Thanks to your post, this issue has been resolved in my programs. Thanks again!!
Tom | 27th July 2007 at 20:13
DUDE,
I know this is old, but man, you saved me. My hosting provide has an older version of PHP, and I was going nuts trying to solve this problem.
THANK YOU
Mike
Mike | 20th March 2010 at 14:12
Fatal error: Nesting level too deep – recursive dependency
i got this error when i use this function too
var_export ($GLOBALS , false);
did any body know way
thank you
astaza | 10th March 2011 at 04:09
astaza,
I get the same error as you when I do a var_export(). I don’t know where in my code to look for the comparison operators, it could be anywhere as the object I am exporting is huge. I have stopped var_exporting for the moment.
Jeffery Fernandez | 5th May 2011 at 09:10
Leave a Comment comment policy
XHTML: you can use these tags - <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>Subscribe to the comments via RSS Feed