Nainstaloval jsem PHP 5.2 V jednom z mých testování počítačů dnes a pár kousky kódu, který dříve pracoval pokuta ve verzi 5.1.6 hodil fatální chyby v nové verzi. Chybová zpráva byla "úroveň vnoření příliš hluboko - rekurzivní závislost?"A trvalo jen velmi málo času
V PHP existují dvě srovnání operátorů, == A ===. Je všeobecně známo, že první není striktní o typu, ale druhý je. Tak, například
echo ( nepravdivé == 0 ); // pravdivý
echo ( nepravdivé === 0 ); // falešný
- 0 je celé číslo a falešné je boolean
Můj problém vznikl z používání non-přísné psaní s objekty.
$= new myObj();
$b = new myObj();
jestliže( $== $ b )
…
To mě nenapadlo, co jsem dělal s tímto kódem. Při porovnávání dvou objektů za použití non-přísné operátor porovnání (==) PHP porovnává všechny vlastnosti objektů a když zápas objekty jsou považovány za rovné. Pokud se neshodují, nejsou stejné. Ve skutečnosti, Máme rekurzivní srovnání všech vlastností každého objektu, a všechny jejich vlastnosti, atd.. až se dostaneme základní datové typy, jako struny a celá čísla.
Jestliže, však, používáme přísné srovnání (===), PHP bude kontrolovat, zda dva objekty jsou naprosto stejné objekt, nejen objekty se stejnými vlastnostmi.
třída MyObj
{
veřejné $ p;
}$= new myObj();
$b = new myObj();
$c = new myObj();
$->p = 1;
$b->p = 1;
$C->p = 2;
echo ( $== $ c ); // falešný
echo ( $== $ b ); // pravdivý
echo ( $=== $ b ); // falešný
Problém nastává, pokud máte kruhové odkazy na své objekty vlastnostech. Tak, například
třída MyObj
{
veřejné $ p;
}
třída OtherObj
{
veřejné $ q;
}$= new myObj();
$b = new otherobj();
$->p = $ b;
$b->q = $; // cyklický odkaz: $->p->=== Q $$c = new myObj();
$d = new otherobj();
$C->p = $ d;
$d->q = $ c;// další kruhové referenční: $C->p->q $ c ===echo ( $== $ c ); // Osudný omyl:
Úroveň vnoření příliš hluboko – rekurzivní závislost?
Aby bylo možné porovnat $ a do $ c, PHP musí porovnávat jejich vlastnosti. Takže logika v PHP jde něco takového: $== $ c Je-li $ a->p == $c->P-li $ a->p->q == $ c->p->q-li $ a->p->q-&p == $ c-$c-&gp-p->q->p etc. na neurčito.
PHP 5.1 Zdálo se, vyžehlit problém nějak (pravděpodobně po určitou úroveň rekurze je prostě vrátil falešný) – a většinou to fungovalo pokutuPHPHP 5.2 správně vyrábí fatální chybu výše.
Jakmile znáte problém, Řešení je jednoduché – použít přísné srovnání.
echo ( $=== $ c ); // falešný (a žádná chyba)
Přísné srovnání jednoduše zkontrolovat, zda dva objekty jsou na stejném místě v paměti, a tak není ani pohled na hodnoty vlastností.
NB. Stejný problém může nastat při použití negované srovnání operátorů (použití !== Místo !=) a při použití in_array (použití in_array třetí parametr uvést přísné srovnání).
