Archive for the ‘Module’ 类别

PHP 错误嵌套太深递归依赖项

3 月 12 日, 2010

我已经安装了 PHP 5.2 在我测试的电脑今天和几位以前在版本中工作正常的代码之一 5.1.6 扔在新版本中的致命错误. 错误消息是"嵌套级别太深 — — 递归依赖项?"和它花了一点时间

追踪问题的根源. 在这里是做了错了.

在 PHP 中有两个比较运算符, = = 和 = = =. 这是众所周知的第一次不是严格的类型,但第二个是. 所以, 举个例子

回声 ( 假 = = 0 ); // 真正的

回声 ( 假 = = = 0 ); // 假

– 0 是一个整数,虚假是一个布尔值

我的问题产生于使用非严格类型化与对象.

$= 新 MyObj();
$b = 新 MyObj();
如果( $= = $b )

我没有考虑过的所作所为与此代码. 当比较两个对象使用非严格比较运算符 (==) PHP 比较的对象的所有属性,如果它们匹配的对象被认为是平等. 如果它们不匹配它们并不相等. 在影响, 我们有一个递归的每个对象的所有属性的比较, 及其所有属性, 等. 直到我们到达基本数据类型,比如字符串和整数.

如果, 然而, 我们使用的是严格的比较 (===), PHP 将检查两个对象是否相同的对象, 不只是具有相同属性的对象.

MyObj 类
{
公共 $p;
}

$= 新 MyObj();
$b = 新 MyObj();
$c = 新 MyObj();
$->p = 1;
$b->p = 1;
$c->p = 2;
回声 ( $= = $c ); // 假
回声 ( $= = $b ); // 真正的
回声 ( $= = = $b ); // 假

如果你有循环引用对象属性中,发生的问题. 所以, 举个例子

MyObj 类
{
公共 $p;
}
OtherObj 类
{
公共 $q;
}

$= 新 MyObj();
$b = 新 OtherObj();
$->p = $b;
$b->q = $a; // 循环引用: $->p->q = = = $a

$c = 新 MyObj();
$d = 新 OtherObj();
$c->p = $d;
$d->q = $c;// 另一种循环引用: $c->p->q = = = $c

回声 ( $= = $c ); // 致命错误:
嵌套级别太深 – 递归依赖项?

为了比较 $a 至 $c, PHP 必须比较其属性. PHP 中的逻辑是这样这样的事情: $如果 = = $c $a->p = = $c->p 如果 $a->p->q = = $c->p->q 如果 $a->p->q->p = = $c->p->q->p 等. 无限期.

PHP 5.1 似乎在某种程度上平息问题 (可能在某些级别的递归后它只被返回 false) – 和通常好的工作. PHP 5.2 正确地产生上述的致命错误.

一旦你知道了这个问题, 答案很简单 – 使用严格的比较.

回声 ( $= = = $c ); // 假 (并且没有错误)

严格的比较将简单地检查这两个对象是否在内存中的同一位置,所以连看都不看属性的值.

注. 在使用否定的比较运算符时,可以出现同样的问题 (使用 !而不是 = = !=) 当使用 in_array (使用 in_array 的第三个参数来指示进行严格比较).