Nainstaloval som PHP 5.2 V jednom z mojich testovaní počítačov dnes a pár kúskami kódu, ktorý predtým pracoval pokuta vo verzii 5.1.6 hodil fatálne chyby v novej verzii. Chybové správa bola "úroveň vnorenia príliš hlboko - rekurzívny závislosť?"A trvalo len veľmi málo času
V PHP existujú dve porovnanie operátorov, == A ===. Je všeobecne známe, že prvý nie je striktné o type, ale druhý je. Tak, napríklad
echo ( nepravdivé == 0 ); // pravdivý
echo ( nepravdivé === 0 ); // falošný
- 0 je celé číslo a falošné je boolean
Môj problém vznikol z používania non-prísne písanie s objektmi.
$a = new MyObj();
$b = new MyObj();
ak( $a == $b )
…
To ma nenapadlo, čo som robil s týmto kódom. Pri porovnávaní dvoch objektov za použitia non-prísne operátor porovnanie (==) PHP porovnáva všetky vlastnosti objektov a keď zápas objekty sú považované za rovné. Ak sa nezhodujú, nie sú rovnaké. V skutočnosti, Máme rekurzívny porovnaní všetkých vlastností každého objektu, a všetky ich vlastnosti, atď. až sa dostaneme základné dátové typy, ako struny a celé čísla.
If, však, používame prísne porovnanie (===), PHP bude kontrolovať, či dva objekty sú úplne rovnaké objekt, nielen objekty s rovnakými vlastnosťami.
trieda MyObj
{
verejné $ p;
}$a = new MyObj();
$b = new MyObj();
$c = new MyObj();
$a->p = 1;
$b->p = 1;
$c->p = 2;
echo ( $a == $c ); // falošný
echo ( $a == $b ); // pravdivý
echo ( $a === $b ); // falošný
Problém nastáva, ak máte kruhové odkazy na svoje objekty vlastnostiach. Tak, napríklad
trieda MyObj
{
verejné $ p;
}
trieda OtherObj
{
verejné $ q;
}$a = new MyObj();
$b = new OtherObj();
$a->p = $ b;
$b->q = $; // cyklický odkaz: $a->p->=== Q $$c = new MyObj();
$d = new OtherObj();
$c->p = $ d;
$d->q = $ c;// ďalšie kruhové referenčné: $c->p->q $ c ===echo ( $a == $c ); // Osudný omyl:
Nesting level too deep – rekurzívny závislosť?
Aby bolo možné porovnať $ a do $ c, PHP musia porovnávať ich vlastnosti. Takže logika v PHP ide niečo takého: $a == $c if $a->p == $c->p if $a->p->q == $c->p->q if $a->p->q->p == $c->p->q->p etc. na neurčito.
PHP 5.1 Zdalo sa, vyžehliť problém nejako (pravdepodobne po určitú úroveň rekurzia je proste vrátil falošný) – a väčšinou to fungovalo pokutu. PHP 5.2 správne vyrába fatálne chybu vyššie.
Akonáhle poznáte problém, Riešenie je jednoduché – použiť prísne porovnanie.
echo ( $a === $c ); // falošný (a žiadna chyba)
Prísne porovnanie jednoducho skontrolovať, či dva objekty sú na rovnakom mieste v pamäti, a tak nie je ani pohľad na hodnoty vlastností.
NB. Rovnaký problém môže nastať pri použití negované porovnaní operátorov (použitie !== Miesto !=) a pri použití in_array (použitie in_array tretí parameter uviesť prísne porovnanie).
