W3docs

clone

Lerne, wie das PHP-Schlüsselwort clone Objekte kopiert, warum es eine flache Kopie erstellt und wie du mit der magischen Methode __clone() tiefe Kopien steuerst.

Das PHP-Schlüsselwort clone

In PHP werden Objekte per Referenz behandelt. Wenn du eine object-Variable mit = einer anderen zuweist, zeigen beide Variablen auf das gleiche Objekt – änderst du eine, ändert sich die andere ebenfalls. Das Schlüsselwort clone bricht diese Verbindung: Es erstellt ein brandneues Objekt, das als Duplikat eines bestehenden beginnt, sodass du die Kopie bearbeiten kannst, ohne das Original zu berühren.

Diese Seite behandelt die clone-Syntax, den Unterschied zwischen einer flachen und einer tiefen Kopie (die häufigste Fehlerquelle bei clone) sowie die magische Methode __clone(), mit der du steuern kannst, was beim Klonen passiert.

Wenn du neu bei Objekten bist, lies zuerst PHP Classes and Objects und Constructors.

Syntax

$copy = clone $original;

clone gibt ein neues Objekt zurück. Das Original bleibt unverändert, und $copy ist eine unabhängige Instanz, deren Eigenschaften aus $original kopiert werden.

Zuweisung vs. clone

Das ist der Grund, warum clone existiert. Bei einer einfachen Zuweisung verweisen beide Variablen auf ein Objekt:

<?php
class Counter
{
    public int $value = 0;
}

$a = new Counter();
$b = $a;          // same object, NOT a copy
$b->value = 10;

echo $a->value . PHP_EOL; // 10 — $a changed too

Verwende clone, um ein wirklich separates Objekt zu erhalten:

<?php
class Counter
{
    public int $value = 0;
}

$a = new Counter();
$b = clone $a;    // independent copy
$b->value = 10;

echo $a->value . PHP_EOL; // 0 — original is untouched
echo $b->value . PHP_EOL; // 10

Ein einfaches Beispiel

<?php
class Car
{
    public string $make;
    public string $model;
    public int $year;

    public function __construct(string $make, string $model, int $year)
    {
        $this->make = $make;
        $this->model = $model;
        $this->year = $year;
    }
}

$original = new Car("Ford", "Mustang", 2022);
$copy = clone $original;

$copy->make = "Chevrolet";
$copy->model = "Corvette";

echo "Original: {$original->make} {$original->model} {$original->year}" . PHP_EOL;
echo "Copy:     {$copy->make} {$copy->model} {$copy->year}" . PHP_EOL;

// Output:
// Original: Ford Mustang 2022
// Copy:     Chevrolet Corvette 2022

Das Ändern von $copy lässt $original unberührt, da es sich um zwei separate Objekte handelt.

Flache Kopie: der häufigste Stolperstein

Standardmäßig erstellt clone eine flache Kopie. Skalare Eigenschaften (strings, ints, booleans) werden per Wert kopiert, aber wenn eine Eigenschaft ein weiteres Objekt enthält, wird nur die Referenz kopiert – sowohl das Original als auch der Klon zeigen dann auf das gleiche verschachtelte Objekt.

<?php
class Engine
{
    public function __construct(public int $horsepower) {}
}

class Car
{
    public function __construct(public Engine $engine) {}
}

$original = new Car(new Engine(300));
$copy = clone $original;

// Both cars still share ONE Engine object
$copy->engine->horsepower = 500;

echo "Original engine: {$original->engine->horsepower} hp" . PHP_EOL;
echo "Copy engine:     {$copy->engine->horsepower} hp" . PHP_EOL;

// Output:
// Original engine: 500 hp
// Copy engine:     500 hp

Das Bearbeiten des Motors des Klons hat auch den Motor des Originals verändert – fast nie das, was man möchte.

Tiefe Kopie mit __clone()

Die magische Methode __clone() wird automatisch auf dem neuen Objekt ausgeführt, direkt nachdem es dupliziert wurde. Verwende sie, um verschachtelte Objekte zu klonen, damit die Kopie eigene unabhängige Objekte erhält (eine tiefe Kopie):

<?php
class Engine
{
    public function __construct(public int $horsepower) {}
}

class Car
{
    public function __construct(public Engine $engine) {}

    public function __clone()
    {
        // Give the clone its own Engine instead of sharing the original's
        $this->engine = clone $this->engine;
    }
}

$original = new Car(new Engine(300));
$copy = clone $original;

$copy->engine->horsepower = 500;

echo "Original engine: {$original->engine->horsepower} hp" . PHP_EOL;
echo "Copy engine:     {$copy->engine->horsepower} hp" . PHP_EOL;

// Output:
// Original engine: 300 hp
// Copy engine:     500 hp

Jetzt haben die beiden Autos separate Motoren, sodass das Ändern des einen das andere nicht beeinflusst. __clone() ist der richtige Ort für alle kopienspezifischen Anpassungen: das Zurücksetzen einer automatisch generierten ID, das Leeren eines gecachten Werts oder das tiefe Kopieren verschachtelter Objekte und object-arrays.

Wann sollte man clone verwenden?

  • Arbeitskopien / Entwürfe – ein Objekt duplizieren, damit ein Benutzer eine Kopie bearbeiten kann, während das Original erhalten bleibt (ähnlich wie „Speichern unter").
  • Prototyp-Muster – ein Objekt vorkonfigurieren und bei Bedarf mit clone neue vorkonfigurierte Instanzen erstellen, statt jedes Mal einen aufwändigen Konstruktor auszuführen.
  • Unveränderlichkeits-Helfer – einen modifizierten Klon zurückgeben, anstatt $this zu mutieren – eine gängige Technik bei Value Objects und DTOs.

Greife auf clone zurück, wenn du gezielt ein zweites, unabhängiges Objekt benötigst; wenn du dasselbe Objekt nur von zwei Stellen aus lesen musst, reicht eine einfache Referenz.

Was zu beachten ist

  • clone erstellt standardmäßig eine flache Kopie – verschachtelte Objekte werden geteilt, nicht dupliziert.
  • Definiere __clone(), um eine tiefe Kopie oder andere kopienspezifische Anpassungen durchzuführen.
  • __clone() läuft auf dem neuen Objekt, wobei $this der Klon ist.
  • Clone ist für Objekte gedacht. Arrays in PHP werden bei der Zuweisung bereits per Wert kopiert und benötigen daher kein clone.

Übungen

Übung
Was macht die Methode __clone() in PHP?
Was macht die Methode __clone() in PHP?
Was this page helpful?