Jeg har installeret PHP 5.2 på en af mine test computere i dag, og et par stykker kode, der tidligere arbejdede nobel i version 5.1.6 kastede fatal fejl i den nye version. Den fejl besked var "Nesting niveau for dybt - rekursiv afhængighed?"Og det tog lidt tid at opspore roden af problemet. Her er hvad jeg havde gjort forkert.
I PHP er der to sammenligning operatører, == Og ===. Det er alment kendt, at den første ikke er streng om type, men den anden er. Så, for example
echo ( false == 0 ); // sandt
echo ( false === 0 ); // false
- 0 er et heltal og falsk er en boolean
Mit problem er opstået ved hjælp af ikke-streng skrive med genstande.
$a = new MyObj();
$b = new MyObj();
hvis( $a == $b )
…
Jeg havde ikke overvejet, hvad jeg gjorde med denne kode. Ved sammenligning af to objekter ved hjælp af ikke-strenge sammenligningsoperator (==) PHP sammenligner alle de egenskaber af objekterne, og hvis de svarer til de genstande anses for at være lig. Hvis de ikke passer de ikke lige. I realiteten, vi har en rekursiv sammenligning af alle de egenskaber for hvert objekt, og alle deres egenskaber, etc.. indtil vi når basale datatyper som strygere og heltal.
If, dog, vi bruger stringent sammenligning (===), PHP vil kontrollere, om de to objekter er nøjagtig de samme objekt, ikke bare objekter med de samme egenskaber.
klasse MyObj
{
offentlig $ p;
}$a = new MyObj();
$b = new MyObj();
$c = new MyObj();
$a->p = 1;
$b->p = 1;
$c->p = 2;
echo ( $a == $c ); // false
echo ( $a == $b ); // sandt
echo ( $a === $b ); // false
Problemet opstår, hvis du har cirkulære referencer i dine objekter ejendomme. Så, for example
klasse MyObj
{
offentlig $ p;
}
klasse OtherObj
{
offentlig $ q;
}$a = new MyObj();
$b = new OtherObj();
$a->p = $ b;
$b->q = $ a; // den cirkulære reference: $a->p->=== Q $ en$c = new MyObj();
$d = new OtherObj();
$c->p = $ d;
$d->q = $ c;// anden cirkulær reference: $c->p->Q === $ cecho ( $a == $c ); // Fatal fejl:
Nesting level too deep – rekursive afhængighed?
For at kunne sammenligne $ en til $ c, PHP skal sammenligne deres egenskaber. Så logikken i PHP går noget som dette: $a == $c if $a->p == $c->p if $a->p->q == $c->p->q if $a->p->q->p == $c->p->q->p etc. ubestemt tid.
PHP 5.1 syntes at glatte over problemet eller anden måde (formentlig efter et vist niveau af rekursion det simpelthen tilbage falsk) – og som regel det fungerede fint. PHP 5.2 korrekt producerer fatal fejl ovenfor.
Når du kender problemet, løsningen er nem – brug stringent sammenligning.
echo ( $a === $c ); // false (og ingen fejl)
Den strenge sammenligning vil blot kontrollere, om de to objekter på samme sted i hukommelsen og så ikke engang se på værdien af de ejendomme.
NB. Det samme problem kan opstå, når du bruger negeret sammenligning erhvervsdrivende (brug !== I stedet for !=) og når du bruger in_array (brug in_array tredje parameter til at angive strenge sammenligning).
