umair
umair

Reputation: 967

PHP object nesting issue

I am trying to create a circular linked list in php which is fairly simple as php objects are references. This means behavior of php objects should be similar to c++ pointers. Following is a simplified implementation of a linked list:

class Node{
    public $next;
}

$node1 = new Node();
$node2 = new Node();

$node1->next = $node2;
$node2->next = $node1;

After implementing this I realized crazy things start happening when you link your objects in a circular list. e.g. you get an error while comparing these objects using == operator:

if($node1 == $node2) //Fatal error: Nesting level too deep - recursive dependency?

I found out correct way to compare these objects is to use strict comparison.

if($node1 === $node2) //Works fine

I think non-strict comparison tries to compare all attributes of object. In doing so it finds out that there is infinite nesting so it reports an error. But what I cannot figure out is why the following works:

if($node1->next == $node2) //Works fine with == rather than ===

Conclusion:

Always use identity operator (===) to compare objects - unless you want compare to return true for similar objects with different instances, but be aware of the nesting issue.

Upvotes: 4

Views: 233

Answers (2)

Michael Mitch
Michael Mitch

Reputation: 839

As far as i know, PHP compare two objects only by looking into their properties indefinitely until ends.

if($node1 == $node2)

 $node1 == $node2?
 if $node1 -> next == $node2->next 
  if $node1->next(node2)->next == $node2->next(node1)->next 
    if $node1->next(node2)->next(node1)->next == $node2->next(node1)->next(node2)->next;

Indefinitely...

if an object has property, it will look into them if you compare two objects.

So, for why your strict comparison works because it will simply check whether the two objects are at the same location in memory and so it do not even look at the values of the properties.

if($node1->next == $node2)

For why comparing if($node1->next == $node2) worked fine i guesses as below: PHP compares for "address" first, if two objects going to be compared have the same address. PHP assumes they must be identical as they resides in the same place.

Like $node1 has an address of 1. And $node2 has an address of 2. $node2->next then have an address of 1. same address, PHP dont want look into properties now, because they resides in the same place.

Also, for your reference. The compare result of "==" and "===" respectively on php.net http://php.net/manual/en/language.oop5.object-comparison.php

Two instances of the same class
o1 == o2 : TRUE
o1 != o2 : FALSE
o1 === o2 : FALSE
o1 !== o2 : TRUE

Two references to the same instance
o1 == o2 : TRUE
o1 != o2 : FALSE
o1 === o2 : TRUE
o1 !== o2 : FALSE

Instances of two different classes
o1 == o2 : FALSE
o1 != o2 : TRUE
o1 === o2 : FALSE
o1 !== o2 : TRUE

Upvotes: 2

jayadev
jayadev

Reputation: 3711

As you have concluded in php object comparison using "==" involves comparing attributes of the object and can become recursive

When using the comparison operator (==), object variables are compared in a simple manner, namely: Two object instances are equal if they have the same attributes and values, and are instances of the same class.

On the other hand, when using the identity operator (===), object variables are identical if and only if they refer to the same instance of the same class.

Now in the latter case it works because you are comparing node2 with node2. For ex:

if($node2 == $node2)  //works since there it can conclude in 1 step both are same objects

while

if($node2->next == $node2) //will still have the recursion issue since it has to follow the links

Upvotes: 1

Related Questions