Archive for the ‘Module’ Kategorie

PHP Fehler Verschachtelung Ebene zu tief rekursive Dependency

12. März, 2010

Ich habe PHP installiert. 5.2 bei einem meiner Tests Computer geklappt heute und ein paar Codezeilen, die zuvor in der version 5.1.6 warf schwerwiegende Fehler in der neuen version. Die Fehlermeldung war "Verschachtelung Ebene zu tief – rekursive Abhängigkeit?"und es dauerte ein wenig Zeit

auf die Spur, die Wurzel des Problems. Hier ist was ich getan hatte falsch.

In PHP gibt es zwei Vergleichsoperatoren, == und ===. Es ist allgemein bekannt, dass die erste nicht streng über Typ aber das zweite ist. Also, Zum Beispiel

Echo ( == false 0 ); // STIMMT

Echo ( falsche === 0 ); // FALSE

– 0 eine ganze Zahl und false ist ein boolescher Wert

Mein Problem entstand aus der Verwendung von nicht-strikte Typisierung mit Objekten.

$eine neue MyObj =();
$b = neue MyObj();
If( $ein $b == )

Ich hatte nicht bedacht, was ich mit diesem Code machte. Vergleicht zwei Objekte, die durch die nicht-strikte Vergleichsoperator (==) PHP vergleicht die Eigenschaften der Objekte und sie passen die Objekte gelten als gleich sein. Wenn sie nicht übereinstimmen, sind sie nicht gleich. In der Tat, Wir haben einen rekursiven Vergleich aller Eigenschaften der einzelnen Objekte, und deren Eigenschaften, etc.. bis wir grundlegende Datentypen wie Strings und Zahlen erreichen.

Wenn, jedoch, Wir verwenden strenge Vergleich (===), PHP wird überprüft, ob die beiden Objekte genau das gleiche Objekt sind, nicht nur Objekte mit den gleichen Eigenschaften.

Klasse MyObj
{
Öffentlichkeit $p;
}

$eine neue MyObj =();
$b = neue MyObj();
$c = neue MyObj();
$ein->p = 1;
$b->p = 1;
$c->p = 2;
Echo ( $ein $c == ); // FALSE
Echo ( $ein $b == ); // STIMMT
Echo ( $ein === $b ); // FALSE

Das Problem entsteht, wenn Sie Zirkuläre Verweise in Ihren Objekteigenschaften haben. Also, Zum Beispiel

Klasse MyObj
{
Öffentlichkeit $p;
}
Klasse OtherObj
{
Öffentlichkeit $q;
}

$eine neue MyObj =();
$b = neue OtherObj();
$ein->p = $b;
$b->Q = $a; // die zirkulären Verweis: $ein->p->Q === $a

$c = neue MyObj();
$d = neues OtherObj();
$c->p = $d;
$d->Q = $c;// ein weiterer zirkulärer Verweis: $c->p->Q === $c

Echo ( $ein $c == ); // Schwerwiegender Fehler:
Ebene zu tief verschachteln – rekursive Abhängigkeit?

Um $a zu $c vergleichen, PHP muss ihre Eigenschaften vergleichen.. So geht die Logik in PHP sowas: $ein == $c Wenn $a ->p == $c ->p wenn $a ->p->Q == $c ->p->Q wenn $a ->p->Q->p == $c ->p->Q->p etc.. auf unbestimmte Zeit.

PHP (Englisch) 5.1 schien das Problem irgendwie glätten (nach einem gewissen Maß an Rekursion kehrte es wahrscheinlich einfach falsch) – und es ging in der Regel gut. PHP (Englisch) 5.2 die oben genannten Fehler korrekt produziert.

Sobald Sie wissen, dass das problem, die Lösung ist einfach – Verwenden Sie strengen Vergleich.

Echo ( $ein === $c ); // FALSE (und kein Fehler)

Der strikte Vergleich prüft einfach, ob sich die beiden Objekte an derselben Stelle im Speicher befinden, und betrachtet daher nicht einmal die Werte der Eigenschaften..

N.B.. Das gleiche Problem kann auftreten, wenn die negierten Vergleichsoperatoren verwendet werden (gebrauchen !== statt !=) und bei der Verwendung von in_array (Verwenden Sie den dritten Parameter von in_array, um einen strikten Vergleich anzuzeigen).