PHP对象嵌套问题

时间:2013-09-12 19:52:07

标签: php reference linked-list nested

我正在尝试在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,但要注意嵌套问题。

2 个答案:

答案 0 :(得分:2)

据我所知, PHP仅通过无限期地查看它们的属性来比较两个对象,直到结束。

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;

<强>无限期...

如果某个对象具有属性,则在比较两个对象时会查看它们。

那么,为什么你的严格比较是有效的,因为它只会检查两个对象是否位于内存中的相同位置,因此它甚至不会查看属性的值。

if($ node1-&gt; next == $ node2)

为什么比较 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