4

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 を返す場合を除きますが、ネストの問題に注意してください。

4

2 に答える 2

2

私の知る限り、PHP は 2 つのオブジェクトを、そのプロパティを無期限に調べることによってのみ比較します。

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;

無期限...

オブジェクトにプロパティがある場合、2 つのオブジェクトを比較するとそれらが調べられます。

したがって、厳密な比較が機能する理由は、2 つのオブジェクトがメモリ内の同じ場所にあるかどうかを単純にチェックし、プロパティの値を調べないためです。

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

if($node1->next == $node2) の比較がうまくいった理由について、以下のように推測します: PHP は、それらが同じ場所に存在するため、同一である必要があると想定します。

$node1 のアドレスが 1 のように、$node2 のアドレスが 2 です。

また、ご参考までに。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
于 2013-09-12T20:07:34.693 に答える