Reputation: 967
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
Reputation: 839
As far as i know, PHP compare two objects only by looking into their properties indefinitely until ends.
$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.
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
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