Menu
Coddy logo textTech

Objektklonen im Detail

Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy. Lektion 61 von 91.

Du hast die magische __clone-Methode bereits früher in diesem Kurs kennengelernt. Sehen wir uns nun den entscheidenden Unterschied zwischen flachem und tiefem Klonen an, wenn Objekte andere Objekte als Eigenschaften enthalten.

Standardmäßig führt PHP beim Klonen eine flache Kopie durch. Skalare Werte werden dupliziert, aber Objekteigenschaften bleiben Verweise auf dieselben Objekte:

<?php
class Address {
    public function __construct(public string $city) {}
}

class Person {
    public function __construct(
        public string $name,
        public Address $address
    ) {}
}

$original = new Person("Alice", new Address("Paris"));
$clone = clone $original;

$clone->name = "Bob";
$clone->address->city = "London";

echo $original->name . " - " . $original->address->city;

Ausgabe:

Alice - London

Beachte, dass das Ändern von $clone->name das Original nicht beeinflusst hat, aber das Ändern der Adressstadt schon! Beide Objekte verwenden dieselbe Address-Instanz.

Um eine tiefe Kopie zu erstellen, bei der verschachtelte Objekte ebenfalls geklont werden, implementiere __clone:

<?php
class Person {
    public function __construct(
        public string $name,
        public Address $address
    ) {}
    
    public function __clone(): void {
        $this->address = clone $this->address;
    }
}

$original = new Person("Alice", new Address("Paris"));
$clone = clone $original;
$clone->address->city = "London";

echo $original->address->city;

Ausgabe:

Paris

Jetzt hat jede Person ihre eigene unabhängige Address. Wenn deine Objekte mehrere verschachtelte Objekte enthalten, musst du jedes einzelne in __clone klonen, um eine echte Unabhängigkeit zwischen dem Original und der Kopie zu erreichen.

challenge icon

Aufgabe

Einfach

Lass uns ein Dokumentverwaltungssystem erstellen, das den Unterschied zwischen flachem und tiefem Klonen demonstriert. Du wirst Dokumente erstellen, die Autoreninformationen enthalten, und sicherstellen, dass das Klonen eines Dokuments eine wirklich unabhängige Kopie erstellt.

Du wirst deinen Code auf drei Dateien verteilen:

  • Author.php: Erstelle eine Author-Klasse, die den Autor eines Dokuments repräsentiert. Verwende Konstruktor-Promotion, um einen öffentlichen $name (String) und eine öffentliche $email (String) zu definieren.
  • Document.php: Erstelle eine Document-Klasse, die einen Autor enthält. Binde die Author-Datei ein. Die Klasse sollte:
    • Konstruktor-Promotion für einen öffentlichen $title (String) und einen öffentlichen $author (Author) verwenden
    • die magische Methode __clone() implementieren, um tiefes Klonen durchzuführen; wenn ein Dokument geklont wird, sollte auch sein Autor geklont werden, damit Änderungen am Autor der Kopie das Original nicht beeinflussen
    • eine Methode getInfo() besitzen, die "[title] by [author name] ([author email])" zurückgibt
  • main.php: Binde die Document-Datei ein. Du erhältst drei Eingaben: einen Dokumenttitel, einen Autorennamen und eine E-Mail-Adresse des Autors.

    Erstelle mit den bereitgestellten Eingaben ein Document mit einem Author. Klone das Dokument anschließend, füge dann an den Autorennamen der Kopie " (Copy)" an und stelle dem Titel der Kopie "Copy of " voran.

    Gib zwei Zeilen aus:

    • Die Informationen des Originaldokuments
    • Die Informationen des geklonten Dokuments

    Wenn dein tiefes Klonen korrekt implementiert ist, sollte der Autor des Originaldokuments auch nach der Änderung des Autors der Kopie unverändert bleiben.

Diese Herausforderung zeigt, warum tiefes Klonen wichtig ist: Ohne eine ordnungsgemäße Implementierung von __clone() würden beide Dokumente dasselbe Author-Objekt gemeinsam nutzen, und eine Änderung an einem Dokument würde sich auf das andere auswirken.

Probier es selbst

<?php

require_once 'Document.php';

// Eingaben lesen
$title = trim(fgets(STDIN));
$authorName = trim(fgets(STDIN));
$authorEmail = trim(fgets(STDIN));

// TODO: Erstelle einen Author mit dem angegebenen Namen und der E-Mail

// TODO: Erstelle ein Document mit dem angegebenen Titel und dem Author

// TODO: Klone das Dokument

// TODO: Ändere den Autorennamen des Klons, indem du " (Copy)" anhängst

// TODO: Ändere den Titel des Klons, indem du "Copy of " voranstellst

// TODO: Gib die Infos des Originaldokuments aus

// TODO: Gib die Infos des geklonten Dokuments aus

?>
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-PHP-Compiler