这一点之前已经提到过(参见 jazfresh at hotmail.com 的备注),但这里再次详细说明,因为对于对象来说,== 和 === 之间的区别非常重要。
对象之间的松散比较 (==) 是递归的:如果正在比较的两个对象的属性本身也是对象,那么这些属性也将使用 == 进行比较。
<?php
class Link
{
public $link; function __construct($link) { $this->link = $link; }
}
class Leaf
{
public $leaf; function __construct($leaf) { $this->leaf = $leaf; }
}
$leaf1 = new Leaf(42);
$leaf2 = new Leaf(42);
$link1 = new Link($leaf1);
$link2 = new Link($leaf2);
echo "比较 Leaf 对象等价性:\$leaf1==\$leaf2 吗?", ($leaf1 == $leaf2 ? "是" : "否"), "\n";
echo "比较 Leaf 对象同一性:\$leaf1===\$leaf2 吗?", ($leaf1 === $leaf2 ? "是" : "否"), "\n";
echo "\n";
echo "比较 Link 对象等价性:\$link1==\$link2 吗?",($link1 == $link2 ? "是" : "否"), "\n";
echo "比较 Link 对象同一性:\$link1===\$link2 吗?", ($link1 === $link2 ? "是" : "否"), "\n";
?>
即使 $link1 和 $link2 包含不同的 Leaf 对象,它们仍然是等价的,因为 Leaf 对象本身是等价的。
实际的结果是,在更适合使用 "===" 的情况下使用 "==" 会导致严重的性能损失,特别是如果对象很大且/或复杂时。事实上,如果对象之间或(递归地)它们的任何属性之间存在任何循环关系,则由于隐含的无限循环,可能会导致致命错误。
<?php
class Foo { public $foo; }
$t = new Foo; $t->foo = $t;
$g = new Foo; $g->foo = $g;
echo "严格同一性:", ($t===$g ? "True" : "False"),"\n";
echo "松散等价性:", ($t==$g ? "True" : "False"), "\n";
?>
因此,应优先使用 "===" 而不是 "==" 来比较对象;如果要比较两个不同的对象的等价性,请尝试通过检查合适的单个属性来进行。(也许 PHP 可以获得一个魔法 "__equals" 方法,用于评估 "=="?:) )