Menu
Coddy logo textTech

Objekt-Klonen im Detail

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

Sie haben bereits früher in diesem Kurs etwas über die magische Methode __clone gelernt. Lassen Sie uns nun den entscheidenden Unterschied zwischen flachem und tiefem Klonen untersuchen, wenn Objekte andere Objekte als Eigenschaften enthalten.

Standardmäßig führt PHP beim Klonen eine flache Kopie (shallow copy) aus. Skalare Werte werden dupliziert, aber Objekteigenschaften bleiben Referenzen 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

Beachten Sie, dass das Ändern von $clone->name das Original nicht beeinflusst hat, aber das Ändern der Stadt in der Adresse schon! Beide Objekte teilen sich dieselbe Address-Instanz.

Um eine tiefe Kopie zu erstellen, bei der auch verschachtelte Objekte geklont werden, implementieren Sie __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

Nun hat jede Person ihre eigene unabhängige Address. Wenn Ihre Objekte mehrere verschachtelte Objekte enthalten, müssen Sie 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 Dokumentenmanagementsystem erstellen, das den Unterschied zwischen flachem (shallow) und tiefem (deep) 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 in drei Dateien organisieren:

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

    Erstelle ein Document mit einem Author unter Verwendung der bereitgestellten Eingaben. Klone das Dokument, ändere dann den Autorennamen des Klons, indem du " (Copy)" anhängst, und ändere den Titel des Klons, indem du "Copy of " voranstellst.

    Gib zwei Zeilen aus:

    • Die Informationen des Originaldokuments
    • Die Informationen des geklonten Dokuments

    Wenn dein Deep Cloning korrekt implementiert ist, sollte der Autor des Originaldokuments unverändert bleiben, selbst nachdem der Autor des Klons geändert wurde.

Diese Herausforderung zeigt, warum Deep Cloning wichtig ist — ohne eine ordnungsgemäße Implementierung von __clone() würden beide Dokumente dasselbe Author-Objekt teilen, und die Änderung des einen würde das andere beeinflussen.

Spickzettel

Standardmäßig führt PHP beim Klonen von Objekten eine flache Kopie (shallow copy) aus. Skalare Werte werden dupliziert, aber Objekteigenschaften bleiben Referenzen auf dieselben Objekte.

Beispiel für flaches Klonen:

<?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

Das Ändern von $clone->name hat keine Auswirkungen auf das Original, aber das Ändern des verschachtelten address-Objekts schon, da beide Objekte dieselbe Address-Instanz teilen.

Um eine tiefe Kopie (deep copy) zu erstellen, bei der auch verschachtelte Objekte geklont werden, implementieren Sie die magische Methode __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

Wenn Objekte mehrere verschachtelte Objekte enthalten, müssen Sie jedes einzelne in __clone klonen, um eine echte Unabhängigkeit zwischen dem Original und der Kopie zu erreichen.

Probier es selbst

<?php

require_once 'Document.php';

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

// TODO: Erstellen Sie einen Autor mit dem angegebenen Namen und der E-Mail-Adresse

// TODO: Erstellen Sie ein Dokument mit dem angegebenen Titel und dem Autor

// TODO: Klonen Sie das Dokument

// TODO: Ändern Sie den Namen des Autors des Klons, indem Sie " (Copy)" anhängen

// TODO: Ändern Sie den Titel des Klons, indem Sie "Copy of " voranstellen

// TODO: Geben Sie die Informationen des Originaldokuments aus

// TODO: Geben Sie die Informationen 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