Entradas con la etiqueta ‘php’

PHP Error de anidamiento nivel demasiado profundo recursiva de dependencia

12 de marzo, 2010

He instalado PHP 5.2 en uno de los ordenadores mis pruebas de hoy y un par de trozos de código que previamente trabajó muy bien en la versión 5.1.6 arrojó errores fatales en la nueva versión. El mensaje de error fue "nivel de anidamiento demasiado profundo - recursive dependencia?"Y tomó un poco de tiempo

para localizar la raíz del problema. Esto es lo que había hecho mal.

En PHP existen dos operadores de comparación, == Y ===. Es generalmente conocido que el primero no es estricta sobre el tipo pero el segundo es. Así, por ejemplo

eco ( == falsa 0 ); // verdadero

eco ( === falsa 0 ); // falso

- 0 es un entero y lo falso es un booleano

Mi problema se plantea el uso de escribir no estricta con los objetos.

$a = new MyObj();
$b = new MyObj();
si( $a == $ b )

No había pensado en lo que estaba haciendo con este código. Cuando se comparan dos objetos usando el operador de comparación no estricta (==) PHP compara todas las propiedades de los objetos y si coinciden con los objetos se consideran iguales. Si no coinciden no son iguales. En efecto, tenemos una comparación recursiva de todas las propiedades de cada objeto, y todas sus propiedades, etc. hasta llegar a los tipos de datos básicos, como cadenas y números enteros.

Si, sin embargo, usamos una comparación estricta (===), PHP comprobará si los dos objetos son exactamente el mismo objeto, no sólo los objetos con las mismas propiedades.

clase MyObj
{
p $ pública;
}

$a = new MyObj();
$b = new MyObj();
$c = new MyObj();
$a->p = 1;
$b->p = 1;
$c->p = 2;
eco ( $a == $ c ); // falso
eco ( $a == $ b ); // verdadero
eco ( $a === $ b ); // falso

El problema se plantea si tiene referencias circulares en sus objetos propiedades. Así, por ejemplo

clase MyObj
{
p $ pública;
}
clase OtherObj
{
pública $ q;
}

$a = new MyObj();
$b = new OtherObj();
$a->p = $ b;
$b->q = $a; // la referencia circular: $a->p->q === $a

$c = new MyObj();
$d = new OtherObj();
$c->p = $ d;
$d->q = $ c;// otra referencia circular: $c->p->q $ c ===

eco ( $a == $ c ); // Fatal error:
El nivel de anidamiento demasiado profundo – dependencia recursiva?

A fin de comparar a $ a $ c, PHP debe comparar sus propiedades. Así que la lógica en PHP es algo como esto: $una c == $ si $ a->p == $c->p si $ a->p->q == $ c->p->q si $ a->p->q-&p == $ c-$c-&gp-p->q->p etc. por tiempo indefinido.

PHP 5.1 parecía suavizar el problema de alguna manera (probablemente después de un cierto nivel de recursividad simplemente devuelve false) – y por lo gePHPal todo salió bien. PHP 5.2 produce correctamente el error fatal por encima de.

Una vez conocido el problema, la solución es fácil – usar la comparación estricta.

eco ( $a === $ c ); // falso (y no hay error)

La comparación estricta simplemente comprobar si los dos objetos están en el mismo lugar en la memoria y por lo tanto ni siquiera mirar a los valores de las propiedades.

N.B. El mismo problema puede surgir cuando se utilizan los operadores de comparación negada (uso !== En lugar de !=) y cuando se utiliza in_array (uso tercer parámetro in_array para indicar comparación estricta).

Compartir y Disfrutar

  • wp socializer sprite mask 16px PHP Error Nesting Level Too Deep Recursive Dependency
  • wp socializer sprite mask 16px PHP Error Nesting Level Too Deep Recursive Dependency
  • wp socializer sprite mask 16px PHP Error Nesting Level Too Deep Recursive Dependency
  • wp socializer sprite mask 16px PHP Error Nesting Level Too Deep Recursive Dependency
  • wp socializer sprite mask 16px PHP Error Nesting Level Too Deep Recursive Dependency
  • wp socializer sprite mask 16px PHP Error Nesting Level Too Deep Recursive Dependency
  • wp socializer sprite mask 16px PHP Error Nesting Level Too Deep Recursive Dependency
  • wp socializer sprite mask 16px PHP Error Nesting Level Too Deep Recursive Dependency
  • wp socializer sprite mask 16px PHP Error Nesting Level Too Deep Recursive Dependency