Instalei o PHP 5.2 nun dos ordenadores o meu exame hoxe e un par de anacos de código, que anteriormente traballou moi ben na versión 5.1.6 xogou erros fatais na nova versión. A mensaxe de erro foi "nivel de nidificación moi profundo - recursive dependencia?"E levou un pouco de tempo
No PHP existen dous operadores de comparación, == E ===. É do coñecemento xeral que o primeiro non é rigorosa sobre o tipo, pero o segundo é. Así, for example
eco ( == False 0 ); // verdadeiro
eco ( === False 0 ); // falso
- 0 é un enteiro e falso é un Boole
O meu problema xurdiu con dixitación non estrita cos obxectos.
$a = new MyObj();
$b = new MyObj();
se( $a == $b )
…
Eu non tiña pensado que eu estaba facendo este código. Cando comparando dous obxectos utilizando o operador de comparación non estrita (==) PHP compara as propiedades dos obxectos e se combinan os obxectos son considerados iguais. Se eles non corresponder, non son iguais. En realidade, temos unha relación recursiva de todas as propiedades de cada obxecto, e todas as súas propiedades, etc. ata chegar a tipos de datos básicos como cadeas e enteiros.
If, con todo, usan comparación estrita (===), PHP ha comprobar que os dous obxectos son exactamente o mesmo obxecto, non só obxectos coas mesmas propiedades.
MyObj clase
{
p public $;
}$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 ); // verdadeiro
eco ( $a === $b ); // falso
O problema xorde cando ten referencias circulares nos seus obxectos de inmobles. Así, for example
MyObj clase
{
p public $;
}
OtherObj clase
{
public $ q;
}$a = new MyObj();
$b = new OtherObj();
$a->p = $ b;
$b->q = $ a; // a referencia circular: $a->p->=== Q $ a$c = new MyObj();
$d = new OtherObj();
$c->p = $ d;
$d->q = $ c;// outra referencia circular: $c->p->q $ c ===eco ( $a == $c ); // Erro fatal:
Asentamento nivel moi profundo – dependencia recursiva?
Co fin de comparar a $ a $ c, PHP debe comparar as súas propiedades. Polo tanto, a lóxica en PHP é algo así como isto: $a == $c if $a->p == $c->p if $a->p->q == $c->p->q if $a->p->q->p == $c->p->q->p etc. indefinidamente.
PHP 5.1 Semella bo sobre o problema de algunha maneira (probablemente despois dun certo nivel de recursão simplemente retornou false) – e, normalmente, fuPHPonou moi ben. PHP 5.2 correctamente produce o erro fatal anterior.
Unha vez que coñece o problema, A solución é fácil – usar comparación estrita.
eco ( $a === $c ); // falso (e ningún erro)
A comparación rigorosa simplemente comprobar que os dous obxectos están no mesmo lugar na memoria e así nin sequera ollar os valores das propiedades.
NB. O mesmo problema pode xurdir cando se utiliza os operadores de comparación rexeitada (utilización !== En vez de !=) and when using in_array (use in_array’s third parameter to indicate strict comparison).
