__clone & Objekt-Klonen
Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy — Lektion 48 von 91.
Wenn Sie in PHP ein Objekt einer anderen Variablen zuweisen, erstellen Sie keine Kopie – beide Variablen zeigen auf dasselbe Objekt. Um eine tatsächliche, unabhängige Kopie zu erstellen, müssen Sie 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;
Ausgabe:
999.99 - 899.99Standardmäßig führt PHP eine flache Kopie (shallow copy) aus – es kopiert alle Eigenschaftswerte direkt. Dies funktioniert gut für skalare Werte, aber Objekte innerhalb Ihres Objekts verweisen weiterhin auf dieselbe Instanz. Die magische Methode __clone() ermöglicht es Ihnen, dieses Verhalten anzupassen:
<?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;
Ausgabe:
Original: 101, Clone: 0Die Methode __clone() wird für das neue Objekt aufgerufen, nachdem die flache Kopie erstellt wurde. Hier setzen Sie IDs zurück, erstellen neue Kopien von verschachtelten Objekten oder führen Bereinigungen durch, die erforderlich sind, damit der Klon wirklich unabhängig ist.
Aufgabe
EinfachLassen Sie uns ein Dokumenten-Versionierungssystem erstellen, das zeigt, wie das Klonen unabhängige Kopien erzeugt und wie die magische Methode __clone() es Ihnen ermöglicht, anzupassen, was passiert, wenn ein Objekt geklont wird.
Sie werden Ihren Code in zwei Dateien organisieren:
Document.php— Erstellen Sie eine KlasseDocument, die ein versioniertes Dokument repräsentiert. Verwenden Sie Constructor Promotion, um ein öffentliches$title(String), ein öffentliches$content(String) und eine öffentliche$version(Integer, Standardwert 1) zu definieren. Fügen Sie eine private Eigenschaft$createdAthinzu, die den aktuellen Zeitstempel speichert (verwenden Siedate('Y-m-d H:i:s')im Konstruktor). Ihr Dokument benötigt:getCreatedAt()— gibt den Erstellungszeitstempel zurück__clone()— wenn ein Dokument geklont wird, sollte die Version um 1 erhöht werden und$createdAtsollte auf den aktuellen Zeitstempel zurückgesetzt werden (der Klon ist eine neue Version, die "jetzt" erstellt wurde)
main.php— Binden Sie die Datei Document ein. Sie erhalten drei Eingaben: einen Titel, einen Inhalt und einen neuen Inhalts-String für die geklonte Version. Erstellen Sie einDocumentmit dem Titel und dem Inhalt. Klonen Sie es dann, um eine neue Version zu erstellen, und aktualisieren Sie den Inhalt des Klons mit dem neuen Inhalts-String. Geben Sie vier Zeilen aus:- Die Version des Originaldokuments
- Die Version des geklonten Dokuments
- Den Inhalt des Originaldokuments
- Den Inhalt des geklonten Dokuments
Dieses System zeigt, wie __clone() es Ihnen ermöglicht zu steuern, was während des Klonens passiert. Das Originaldokument behält seine Version und Erstellungszeit, während der Klon automatisch zu einer neuen Version mit einem frischen Zeitstempel wird – ideal für die Verfolgung der Dokumentenhistorie, bei der jeder Klon eine neue Revision darstellt.
Spickzettel
Um eine unabhängige Kopie eines Objekts zu erstellen, verwenden Sie das Schlüsselwort clone:
<?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;
// Ausgabe: 999.99 - 899.99
Standardmäßig führt PHP eine flache Kopie (shallow copy) aller Eigenschaftswerte durch. Um das Klonverhalten anzupassen, verwenden Sie die magische Methode __clone():
<?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;
// Ausgabe: Original: 101, Clone: 0
Die Methode __clone() wird auf dem neuen Objekt aufgerufen, nachdem die flache Kopie erstellt wurde. Dies ermöglicht es Ihnen, Eigenschaften zurückzusetzen oder unabhängige Kopien von verschachtelten Objekten zu erstellen.
Probier es selbst
<?php
require_once 'Document.php';
// Eingaben lesen
$title = trim(fgets(STDIN));
$content = trim(fgets(STDIN));
$newContent = trim(fgets(STDIN));
// TODO: Erstellen Sie ein Dokument mit dem Titel und dem Inhalt
// TODO: Klonen Sie das Dokument, um eine neue Version zu erstellen
// TODO: Aktualisieren Sie den Inhalt des Klons auf die neue Inhaltszeichenfolge
// TODO: Geben Sie vier Zeilen aus:
// 1. Die Version des Originaldokuments
// 2. Die Version des geklonten Dokuments
// 3. Der Inhalt des Originaldokuments
// 4. Der Inhalt des geklonten Dokuments
?>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 die OOPKlassen vs. ObjekteDas $this-SchlüsselwortMethodenEigenschaftenKonstruktor (__construct)Destruktor (__destruct)Rückblick - Einfacher Taschenrechner4Vererbung
Grundlagen der VererbungDas parent:: SchlüsselwortMethoden überschreibenDas final SchlüsselwortAbstrakte KlassenZusammenfassung – Mitarbeiter-Hierarchie7Kapselung
Public, Protected, PrivateZugriffsmodifikatoren im DetailGetter und SetterInformation HidingConstructor Promotion (8.0)Zusammenfassung – Studentenverwaltungssystem2Namensräume & Autoloading
Einführung in NamensräumeDas use-SchlüsselwortPSR-4 Autoloading-StandardComposer AutoloaderZusammenfassung – Organisiertes Projekt5Interfaces & Verträge
Einführung in InterfacesInterfaces implementierenMehrfache Interface-ImplementierungInterface vs. Abstrakte KlasseType Hinting mit InterfacesZusammenfassung – Formen-Rechner8Magische Methoden
Einführung in magische Methoden__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Objekt-Klonen__serialize & __unserializeZusammenfassung - Eigene Collection11Typsystem & Fehlerbehandlung
TypdeklarationenNullable-TypenUnion- & Intersection-TypenException-KlassenEigene Exception-HierarchieTry, Catch, FinallyZusammenfassung - Formular-Validator14Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen3Klasseneigenschaften
Instanz- vs. statische EigenschaftenKonstanten in KlassenStatische Methoden & EigenschaftenPrivate & geschützte EigenschaftenReadonly-Eigenschaften (PHP 8.1)Zusammenfassung – Bankkonto-Manager6Polymorphismus
Method Overriding erneut betrachtetPolymorphismus über InterfacesType Hinting & Union TypesLate Static BindingZusammenfassung – Payment Processor9Traits
Einführung in TraitsVerwendung mehrerer TraitsKonfliktlösung bei TraitsAbstrakte Methoden in TraitsTraits vs. Vererbung12Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterObserver-MusterStrategy-Muster15Abschlussherausforderungen
E-Learning-PlattformBanksystemSpielcharakter-EntwicklungFahrzeugvermietung