__clone & Objektklonen
Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy. Lektion 48 von 91.
Wenn du in PHP ein Objekt einer anderen Variablen zuweist, erstellst du keine Kopie – beide Variablen verweisen auf dasselbe Objekt. Um eine tatsächlich unabhängige Kopie zu erstellen, musst du das Schlüsselwort clone verwenden:
<?php
class Product {
public function __construct(
public string $name,
public float $price
) {}
}
$original = new Product("Laptop", 999.99);
$copy = clone $original;
$copy->price = 899.99;
echo $original->price . " - " . $copy->price;
Output:
999.99 - 899.99Standardmäßig führt PHP eine flache Kopie durch – dabei werden alle Eigenschaftswerte direkt kopiert. Das funktioniert für skalare Werte gut, aber Objekte innerhalb deines Objekts verweisen weiterhin auf dieselbe Instanz. Mit der magischen Methode __clone() kannst du dieses Verhalten anpassen:
<?php
class Order {
public function __construct(
public int $id,
public array $items = []
) {}
public function __clone(): void {
$this->id = 0;
$this->items = [];
}
}
$order1 = new Order(101, ["Book", "Pen"]);
$order2 = clone $order1;
echo "Original: " . $order1->id . ", Clone: " . $order2->id;
Output:
Original: 101, Clone: 0Die Methode __clone() wird auf dem neuen Objekt aufgerufen, nachdem die flache Kopie erstellt wurde. Hier setzt du IDs zurück, erstellst frische Kopien verschachtelter Objekte oder führst eine erforderliche Bereinigung durch, damit der Klon wirklich unabhängig ist.
Aufgabe
EinfachErstellen wir ein Dokumentversionierungssystem, das veranschaulicht, wie das Klonen unabhängige Kopien erstellt und wie die magische Methode __clone() anpasst, was beim Klonen eines Objekts geschieht.
Du organisierst deinen Code über zwei Dateien:
Document.php: Erstelle eineDocument-Klasse, die ein versioniertes Dokument darstellt. Verwende Konstruktor-Promotion, um einen öffentlichen$title(String), einen öffentlichen$content(String) und eine öffentliche$version(Ganzzahl, standardmäßig auf 1 gesetzt) zu definieren. Füge eine private$createdAt-Eigenschaft hinzu, die den aktuellen Zeitstempel speichert (verwendedate('Y-m-d H:i:s')im Konstruktor). Dein Dokument benötigt:getCreatedAt(): gibt den Erstellungszeitstempel zurück__clone(): Wenn ein Dokument geklont wird, soll die Version um 1 erhöht und$createdAtauf den aktuellen Zeitstempel zurückgesetzt werden (der Klon ist eine neue Version, die „jetzt“ erstellt wurde).
main.php: Binde die Document-Datei ein. Du erhältst drei Eingaben: einen Titel, einen Inhalt und eine neue Inhaltszeichenkette für die geklonte Version. Erstelle einDocumentmit dem Titel und dem Inhalt. Klone es anschließend, um eine neue Version zu erstellen, und aktualisiere den Inhalt des Klons mit der neuen Inhaltszeichenkette. Gib vier Zeilen aus:- Die Version des ursprünglichen Dokuments
- Die Version des geklonten Dokuments
- Den Inhalt des ursprünglichen Dokuments
- Den Inhalt des geklonten Dokuments
Dieses System zeigt, wie __clone() dir ermöglicht zu steuern, was während des Klonens geschieht. Das ursprüngliche Dokument behält seine Version und seinen Erstellungszeitpunkt, während der Klon automatisch zu einer neuen Version mit einem aktuellen Zeitstempel wird – perfekt, um den Dokumentverlauf nachzuverfolgen, bei dem jeder Klon eine neue Überarbeitung darstellt.
Probier es selbst
<?php
require_once 'Document.php';
// Eingaben lesen
$title = trim(fgets(STDIN));
$content = trim(fgets(STDIN));
$newContent = trim(fgets(STDIN));
// TODO: Erstelle ein Document mit dem title und dem content
// TODO: Klone das Document, um eine neue Version zu erstellen
// TODO: Aktualisiere den content des Klons auf den neuen content-String
// TODO: Gib vier Zeilen aus:
// 1. Die version des originalen Documents
// 2. Die version des geklonten Documents
// 3. Der content des originalen Documents
// 4. Der content des geklonten Documents
?>Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in OOPKlassen vs. ObjekteDas Schlüsselwort $thisMethodenEigenschaftenKonstruktor (__construct)Destruktor (__destruct)Rückblick – Einfacher Taschenrechner4Vererbung
Grundlegende VererbungDas Schlüsselwort parent::MethodenüberschreibungDas Schlüsselwort finalAbstrakte KlassenRückblick – Mitarbeiterhierarchie7Kapselung
Öffentlich, geschützt, privatZugriffsmodifikatoren im DetailGetter und SetterInformationsverbergungKonstruktor-Promotion (8.0)Wiederholung – System zur Verwaltung von Schülerdatensätzen2Namespaces & Autoloading
Einführung in NamespacesDas use-SchlüsselwortPSR-4-Autoloading-StandardComposer-AutoloaderRückblick – Organisiertes Projekt5Schnittstellen & Verträge
Einführung in SchnittstellenSchnittstellen implementierenMehrere Schnittstellen implementierenSchnittstelle vs. abstrakte KlasseTyp-Hinweise mit SchnittstellenRückblick – Formrechner8Magische Methoden
Einführung in magische Methoden__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Objektklonen__serialize & __unserializeRückblick – Benutzerdefinierte Sammlung11Typsystem & Fehlerbehandlung
TypdeklarationenNullable-TypenUnion- & Intersection-TypenException-KlassenBenutzerdefinierte Exception-HierarchieTry, Catch, FinallyRückblick – Formularvalidator14Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen3Klassen-Eigenschaften
Instanz- vs. statische EigenschaftenKonstanten in KlassenStatische Methoden & EigenschaftenPrivate & geschützte EigenschaftenSchreibgeschützte Eigenschaften (PHP 8.1)Zusammenfassung – Bankkonto-Manager6Polymorphie
Methodenüberschreibung erneut betrachtetPolymorphie über SchnittstellenTyp-Hinweise & Union-TypenSpätes statisches BindenRückblick – Zahlungsabwickler9Traits
Einführung in TraitsMehrere Traits verwendenAuflösung von Trait-KonfliktenAbstrakte Methoden in TraitsTraits vs. Vererbung12Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterObserver-MusterStrategy-Muster15Abschließende Herausforderungen
E-Learning-PlattformBankingsystemEntwicklung einer SpielfigurFahrzeugvermietungÜbe selbstständig: Online-PHP-Compiler