Ho installato PHP 5.2 a uno dei miei computer di prova di oggi e un paio di pezzi di codice che in precedenza ha lavorato bene in versione 5.1.6 gettò errori fatali nella nuova versione. Il messaggio di errore era "troppo profondo livello di nidificazione - recursive dipendenza?"E ci è voluto un po 'di tempo
In PHP ci sono due operatori di confronto, == E ===. E 'noto che la prima non è rigido sul tipo, ma la seconda è. Così, for example
eco ( == false 0 ); // vero
eco ( === false 0 ); // falso
- 0 è un intero e falso è un valore booleano
Il mio problema è sorto da usare digitando non rigorosa con gli oggetti.
$a = new MyObj();
$b = new MyObj();
se( $a == $b )
…
Non avevo considerato quello che stavo facendo con questo codice. Quando si confrontano due oggetti utilizzando l'operatore di confronto non-strict (==) PHP mette a confronto tutte le proprietà degli oggetti e se corrispondono gli oggetti sono considerati uguali. Se esse non corrispondono non sono uguali. Infatti, abbiamo un confronto ricorsivo di tutte le proprietà di ciascun oggetto, e tutte le loro proprietà, ecc. fino a raggiungere tipi di dati fondamentali come stringhe e numeri interi.
If, tuttavia, usiamo il confronto rigoroso (===), PHP verificherà se i due oggetti sono esattamente lo stesso oggetto, non solo oggetti con le stesse proprietà.
classe MyObj
{
p $ pubblico;
}$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 ); // vero
eco ( $a === $b ); // falso
Il problema sorge se si dispone di riferimenti circolari negli oggetti immobili. Così, for example
classe MyObj
{
p $ pubblico;
}
classe OtherObj
{
pubblico $ q;
}$a = new MyObj();
$b = new OtherObj();
$a->p = $ b;
$b->q = $ a; // il riferimento circolare: $a->p->=== Q $ a$c = new MyObj();
$d = new OtherObj();
$c->p = $ d;
$d->q = $ c;// un altro riferimento circolare: $c->p->q $ c ===eco ( $a == $c ); // Fatal error:
Nesting level too deep – dipendenza ricorsiva?
Al fine di confrontare a $ a $ c, PHP deve confrontare le loro proprietà. Quindi la logica in PHP va qualcosa come questo: $a == $c if $a->p == $c->p if $a->p->q == $c->p->q if $a->p->q->p == $c->p->q->p etc. indefinitamente.
PHP 5.1 sembrava di appianare il problema in qualche modo (probabilmente dopo un certo livello di ricorsione semplicemente restituito false) – e di solito ha funzionato bene. PHP 5.2 produce correttamente l'errore fatale di sopra.
Una volta che conosci il problema, la soluzione è semplice – uso rigoroso confronto.
eco ( $a === $c ); // falso (e nessun errore)
Il confronto rigoroso si limiterà a verificare se i due oggetti sono nella stessa posizione in memoria e quindi non guardano neanche i valori delle proprietà.
NB. Lo stesso problema può verificarsi quando si usano gli operatori di confronto negato (uso !== Invece di !=) e quando si usa in_array (terzo parametro in_array uso per indicare il confronto rigoroso).
