Benutzer-Werkzeuge

Webseiten-Werkzeuge


php:clone

Objekte klonen

In PHP können Objekte ganz einfach geklont, also dupliziert, werden:

$clone_object = clone $original_object;

Mögliche Probleme beim Klonen

Allerdings werden herbei nur die direkten Eigenschaften des Objektes, aber nicht etwa angehängte, abhängige Objekte dupliziert. Das führt z. B. bei der Benutzung vom DOM-Objekten zu Problemen, da diese nur einmal in einem DOM-Dokument angehängt werden können. Das Problem soll durch das nachfolgende ausführliche Beispiel verdeutlicht werden:

clone_example.php
class DOM_Object_1 {
 
    private $DOM;
    public $DOM_Object_2;
 
    public function __construct( \DOMDocument $SLDDOM ) {
        $this->DOM = $SLDDOM;
    }
 
    public function __clone() {
        $this->DOM_Object_2 = clone $this->DOM_Object_2;
    }
 
    public function getDOMNode() {
 
        $fragment = $this->DOM->createDocumentFragment();
        $node = $fragment->appendChild( $this->DOM->createElement( "Knoten_1" ) );
        $node->appendChild( ( $this->DOM->createTextNode( "Textinhalt 1" )) ) ;
 
        if( isset( $this->DOM_Object_2 ) ) {
            $font = $node->appendChild( $this->DOM->createElement( "DOM_Object_2" ) );
            $font->appendChild( $this->DOM_Object_2 );
        }
 
        return $fragment;
    }
}
 
class DOM_Object_2
{
    private $DOM;
 
    public function __construct(\DOMDocument $SLDDOM)
    {
        $this->DOM = $SLDDOM;
    }
 
    public function getDOMNode()
    {
        $fragment = $this->DOM->createDocumentFragment();
        $node = $fragment->appendChild($this->DOM->createElement( "Knoten_2" ) );
        $node->appendChild(($this->DOM->createTextNode( "Textinhalt 2" ) ) );
        return $fragment;
    }
}
 
$DOM = new \DOMDocument;
$DOM->preserveWhiteSpace = false;
$DOM->formatOutput = true;
 
$root = $DOM->appendChild( $DOM->createElement( 'root' ) );
 
$DOM_Object_1 = new DOM_Object_1( $DOM );
$DOM_Object_2 = new DOM_Object_2( $DOM );
 
$DOM_Object_1->DOM_Object_2 = $DOM_Object_2->getDOMNode();
 
$root->appendChild( $DOM_Object_1->getDOMNode() );
 
echo $DOM->saveXML();

Wenn bei diesem Beispiel ein weiteres DOM-Objekt aus der Klasse DOM_Object_1 erzeugt werden soll wird er folgende Fehler ausgelöst:

Warning: DOMNode::appendChild(): Document Fragment is empty in C:\xampp\htdocs\Development\SLD\clone_example.php on line 24

Auch das Klonen des Objektes durch folgenden Code verschafft zunächst keine Abhlife, da das an DOM_Object_1 auch nach dem Klonen nach wie vor auf das original verknüpfte DOM_Object_2 verweist:

$clone_DOM_Object_1 = clone $DOM_Object_1;
$root->appendChild( $clone_DOM_Object_1->getDOMNode() );
 
$clone_DOM_Object_1 = clone $DOM_Object_1;
$root->appendChild( $clone_DOM_Object_1->getDOMNode() );

Die Lösung

Speziell für die Lösung dieses Problems kann dem Objekt eine Methode „clone()“ hinzugefügt werden. Hier können abweichende Anfangswerte definiert werden, die nach dem Klonen eines Objektes zur Verfügung stehen sowie auch für unseren Fall das Klonen von abhängigen Objekten erzwungen werden:

class DOM_Object_1 {
    ...
 
    public function __clone() {
        $this->DOM_Object_2 = clone $this->DOM_Object_2;
    }
 
    ...
}

Das DOM_Object_1 muss jetzt natürlich auch vor jedem Aufruf geklont werden, damit die neue Methode der Klasse aufgerufen wird.

Hinweis: Die „__clone()“-Methode eines Objektes kann nicht direkt aufgerufen werden.

php/clone.txt · Zuletzt geändert: 2015/12/19 00:00 (Externe Bearbeitung)