Composite-Objekte klonen (PHP5)

Hallo,

wenn man Composite-Objekte klonen möchte, also aus gleichartigen
Objekten zusammengesetzte, dann muss man sich ja sehr genau überlegen,
was man eigentlich klonen will.

Ein Beispiel.

class Node {
public $children = array();
public $property = array();
//...
}

wobei die Children wiederum Nodes sind. Es gibt eine Methode addChild():

function addChild(Node $child) {
$this->children[] = $child;

/* let the child inherit the properties */
foreach ($this->property as $key=>$value) {
$child->property[$key] = $value;
}
}

Wen man nun eine Node klont, will man ja *eigentlich* nicht das, was
clone() standardmäßig macht: Es würde eine neue Node erzeugen, mit
denselben Properties, aber eben auch die selben Kinder referenzieren.
Ich möchte aber, dass clone() neue Kinder erzeugt, die wiederum gleiche
Properties wie die ursprünglichen haben, kurz: ich will den Baum klonen.

mein erster Ansatz

function __clone() {
$node = new Node();
foreach ($this->property as $key=>$value) {
$node->property[$key] = $value;
}

foreach ($this->children as $index=>$child) {
$node->addChild( clone ($child));
}
}

führte seltsamerweise dazu, dass die kinder identische Kinder hatten
(also die Enkel waren nicht das Gleiche, sondern dasselbe, identische
Objekt).

Hab ich hier irgendwas verpasst oder gibt es ein Problem mit clone()?

Servus,
Konni

P.S. die üblichen Überprüfungen ob children bzw. property überhaupt
existieren und Elemente haben, habe ich nur hier der Übersichtlichkeit
wegen weggelassen.


Ein einfaches "clone $node" tut es nicht.




--
Inzwischen ohne Signatur
kscheller [ Fr, 16 November 2007 15:02 ] [ ID #1872724 ]

Re: Composite-Objekte klonen (PHP5)

..oO(Konni Scheller)

>Wen man nun eine Node klont, will man ja *eigentlich* nicht das, was
>clone() standardmäßig macht: Es würde eine neue Node erzeugen, mit
>denselben Properties, aber eben auch die selben Kinder referenzieren.
>Ich möchte aber, dass clone() neue Kinder erzeugt, die wiederum gleiche
>Properties wie die ursprünglichen haben, kurz: ich will den Baum klonen.
>
>mein erster Ansatz
>
>function __clone() {
> $node = new Node();
> foreach ($this->property as $key=>$value) {
> $node->property[$key] = $value;
> }
>
> foreach ($this->children as $index=>$child) {
> $node->addChild( clone ($child));
> }
>}
>
>führte seltsamerweise dazu, dass die kinder identische Kinder hatten
>(also die Enkel waren nicht das Gleiche, sondern dasselbe, identische
>Objekt).
>
>Hab ich hier irgendwas verpasst oder gibt es ein Problem mit clone()?

Ich hab __clone() bisher nicht verwendet, aber laut Handbuch wird
grundsätzlich immer erst eine "normale" 1:1 Kopie des Objektes angelegt
und danach, sofern vorhanden, die __clone()-Methode des gerade erzeugten
Klons aufgerufen.

Es sollte also ausreichen, in Deinem __clone() sämtliche Kindknoten zu
durchlaufen und ebenfalls durch Klone zu ersetzen, so im Sinne von

function __clone() {
foreach ($this->children as $index => $child) {
$this->children[$index] = clone $child;
}
}

(ungetestet)

Micha
Michael Fesser [ Fr, 16 November 2007 16:33 ] [ ID #1872727 ]

Re: Composite-Objekte klonen (PHP5)

Michael Fesser <netizen [at] gmx.de> wrote:

> Ich hab __clone() bisher nicht verwendet, aber laut Handbuch wird
> grundsätzlich immer erst eine "normale" 1:1 Kopie des Objektes angelegt
> und danach, sofern vorhanden, die __clone()-Methode des gerade erzeugten
> Klons aufgerufen.

Hm, das würde bedeuten, dass Node bereits Kinder *hat*, wenn ich meine
dazu bastle.

<gehirn location="konni">ratata ratata *klick*</gehirn>

Servus,
Konni

--
Inzwischen ohne Signatur
kscheller [ Fr, 16 November 2007 18:23 ] [ ID #1872728 ]
PHP » de.comp.lang.php.misc » Composite-Objekte klonen (PHP5)

Vorheriges Thema: loadXML extrem langsam - wieso?
Nächstes Thema: Teilweises auslesen/ausgeben von includierten Dateien