我正在尝试在php中创建一个循环链接列表,这非常简单,因为php对象是引用。这意味着php对象的行为应该类似于c ++指针。以下是链接列表的简化实现:
class Node{
public $next;
}
$node1 = new Node();
$node2 = new Node();
$node1->next = $node2;
$node2->next = $node1;
实现这一点后,我意识到当您在圆形列表中链接对象时,会发生疯狂的事情。例如使用==运算符比较这些对象时出错:
if($node1 == $node2) //Fatal error: Nesting level too deep - recursive dependency?
我发现比较这些对象的正确方法是使用严格的比较。
if($node1 === $node2) //Works fine
我认为非严格比较试图比较对象的所有属性。在这样做时,它发现存在无限嵌套,因此它报告错误。但我无法弄清楚为什么以下工作:
if($node1->next == $node2) //Works fine with == rather than ===
结论:
始终使用标识运算符(===)来比较对象 - 除非您希望比较为具有不同实例的类似对象返回true,但要注意嵌套问题。
答案 0 :(得分:2)
据我所知, PHP仅通过无限期地查看它们的属性来比较两个对象,直到结束。
$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;
<强>无限期... 强>
如果某个对象具有属性,则在比较两个对象时会查看它们。
那么,为什么你的严格比较是有效的,因为它只会检查两个对象是否位于内存中的相同位置,因此它甚至不会查看属性的值。
为什么比较 if($ node1-&gt; next == $ node2)工作正常,我猜如下: 如果要比较的两个对象具有相同的地址,PHP首先比较“地址”。 PHP假设它们必须相同,因为它们位于同一个地方。
就像$ node1的地址为1。 $ node2的地址为2。 $ node2-&gt;接下来的地址为1。 相同的地址,PHP现在不想查看属性,因为它们位于同一个地方。
另外,供您参考。 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
答案 1 :(得分:1)
正如你在php对象中总结的那样,使用“==”比较涉及比较对象的属性并且可以变为递归
使用比较运算符(==)时,对象变量是 以简单的方式进行比较,即:两个对象实例是否相等 它们具有相同的属性和值,并且是实例 同一个班级。
另一方面,当使用身份运算符(===),对象时 当且仅当它们引用同一个实例时,变量才相同 同一个班级。
现在在后一种情况下它可行,因为您正在将node2与node2进行比较。例如:
if($node2 == $node2) //works since there it can conclude in 1 step both are same objects
,而
if($node2->next == $node2) //will still have the recursion issue since it has to follow the links