2011-01-07 12 views
6

Ich habe eine Eltern-Kind-OO-Beziehung. Parent objects hat viele untergeordnete Objekte und jedes untergeordnete Objekt weiß über seine Eltern als Referenz.PHP-Objekt Eltern/Kind Rekursion

Die Eltern können auch ein Kind sein (im Grunde ist es ein Baum).

Wenn ich eine var_dump() auf das Wurzelobjekt sagt es [ „Eltern“] =>RECURSION viele Male und die erzeugte Beschreibung wirklich lang sein.

Ich frage mich, ob ich etwas falsch mache. Wenn ja, interessiert mich die "Best Practice".

Danke für die Hilfe!

+0

ein Code wäre nett! –

+1

Es klingt wie Sie haben einen Zyklus in Ihrem Diagramm (ein Elternteil, das auch ein Kind eines seiner Nachkommen ist), aber ohne Code oder Beispieldaten zu sehen, ist es schwer zu sagen, sicher. – FrustratedWithFormsDesigner

+0

Solange Sie sicher sind, dass die Rekursion nicht zu tief ist, ist es in Ordnung. Andernfalls können Probleme auftreten, z. Codierung des Objekts mit JSON. – usoban

Antwort

12

Sie tun nichts falsches; Sie haben einen Elternteil, der eine Referenz auf seine Kinder hat, und jedes Kind hat eine Referenz zurück zu seinem Elternteil. Wenn Sie das Stammobjekt var_dump() durchlaufen, iteriert es über die untergeordneten Elemente, um sie zu drucken, und da jedes untergeordnete Element einen Verweis auf das übergeordnete Element hat, wird es erneut ausgeführt. Da dies normalerweise zu einer Endlosschleife führen würde (Eltern -> Kind -> Eltern -> Kind -> ...), führt PHP eine Liste von Objekten, die es bereits besucht hat, und wenn es eines entdeckt, versucht es nicht es wieder, sondern stattdessen "RECURSION".

Das einzige, worauf zu achten ist, ist, dass PHP Referenzzählung für seine Speicherbereinigung verwendet, und zirkuläre Konstrukte wie diese selbst nicht auflösen. Dies führt dazu, dass das Skript Speicher ausgibt, was möglicherweise kein Problem darstellt. Um dies zu beheben, müssen Sie manuell bereinigen: Bevor das übergeordnete Objekt den Gültigkeitsbereich verlässt, müssen Sie alle übergeordneten Zeiger auf null setzen.

Siehe auch: http://bugs.php.net/bug.php?id=33595

+0

Speicherverlust scheint ab PHP 5.3 behoben zu sein: (siehe die letzten 2 Kommentare unter: https://bugs.php.net/bug.php?id=33595) –

6

Die var_dump Funktion geht über den Objektgraph alle zugänglichen Daten Ihrer Objekte rekursiv und drucken. Versuchen Sie nun, das folgende Diagramm in Englisch zu setzen.

 has    var_dump: 
Parent ----> Child   "The Parent object has a child object" 
^    |    "That Child object has a Parent Object" 
|______________| has    "That Parent object …" 

Wenn PHP nicht schlau genug wäre, diese Rekursion zu erkennen, würde es unendlich laufen. Stattdessen erkennt es, dass es das Objekt zuvor ausgegeben hat und dumps RECURSION. Du machst nichts falsch.

Click here for another explanation

0

Die einzige Möglichkeit, rekursive Referenzen vermeiden kann, ist, wenn eine „umgekehrte Baum“ Gebäude, das nur dann sinnvoll ist, das Sie vom Kind zum Vater suchen möchten, ohne die Geschwister zu kennen. Wie:

class Foo { 
    protected $parent; 

    public function __construct(Foo $parent = null) { 
     $this->parent = $parent; 
    } 

    public function getParent() { 
     return $this->parent; 
    } 
} 

$a = new Foo; 
$b = new Foo($a); 
$c = new Foo($b); 

Also, von $c können Sie bis zu dem Wurzelknoten verfolgen, $a zu sein, ohne rekursive Referenzen.

Wenn Sie vom Stammknoten zu den Kindern wechseln müssen, gibt es keine andere Lösung als das, was Sie bereits getan haben, was korrekt ist.