Menu
Coddy logo textTech

__clone i klonowanie obiektów

Część sekcji Programowanie obiektowe ścieżki PHP w Coddy. Lekcja 48 z 91.

Gdy przypisujesz jeden obiekt do innej zmiennej w PHP, nie tworzysz kopii — obie zmienne wskazują na ten sam obiekt. Aby utworzyć rzeczywiście niezależną kopię, musisz użyć słowa kluczowego 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;

Wynik:

999.99 - 899.99

Domyślnie PHP wykonuje płytką kopię — kopiuje bezpośrednio wszystkie wartości właściwości. Działa to dobrze w przypadku wartości skalarnych, ale obiekty znajdujące się wewnątrz Twojego obiektu nadal odwołują się do tej samej instancji. Metoda magiczna __clone() pozwala dostosować to zachowanie:

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

Wynik:

Original: 101, Clone: 0

Metoda __clone() jest wywoływana dla nowego obiektu po utworzeniu płytkiej kopii. To tutaj resetujesz identyfikatory, tworzysz nowe kopie zagnieżdżonych obiektów lub wykonujesz wszelkie niezbędne czynności porządkowe, aby klon był całkowicie niezależny.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system wersjonowania dokumentów, który pokazuje, jak klonowanie tworzy niezależne kopie oraz jak magiczna metoda __clone() pozwala dostosować zachowanie obiektu podczas klonowania.

Rozmieścisz swój kod w dwóch plikach:

  • Document.php: Utwórz klasę Document, która reprezentuje wersjonowany dokument. Użyj promocji konstruktora, aby zdefiniować publiczne $title (ciąg znaków), publiczne $content (ciąg znaków) oraz publiczne $version (liczbę całkowitą, której wartość domyślna wynosi 1). Dodaj prywatną właściwość $createdAt, która przechowuje bieżący znacznik czasu (w konstruktorze użyj date('Y-m-d H:i:s')). Twój dokument powinien zawierać:
    • getCreatedAt(): zwraca znacznik czasu utworzenia
    • __clone(): podczas klonowania dokumentu wersja powinna zwiększyć się o 1, a wartość $createdAt powinna zostać ustawiona na bieżący znacznik czasu (klon to nowa wersja utworzona „teraz”)
  • main.php: Dołącz plik Document. Otrzymasz trzy dane wejściowe: tytuł, treść oraz nowy ciąg znaków z treścią dla sklonowanej wersji. Utwórz obiekt Document z tytułem i treścią. Następnie sklonuj go, aby utworzyć nową wersję, i zaktualizuj treść klonu, ustawiając nowy ciąg znaków. Wypisz cztery wiersze:
    • Wersję oryginalnego dokumentu
    • Wersję sklonowanego dokumentu
    • Treść oryginalnego dokumentu
    • Treść sklonowanego dokumentu

Ten system pokazuje, jak __clone() pozwala kontrolować przebieg klonowania. Oryginalny dokument zachowuje swoją wersję i czas utworzenia, a klon automatycznie staje się nową wersją z aktualnym znacznikiem czasu. To idealne rozwiązanie do śledzenia historii dokumentu, w której każdy klon reprezentuje nową rewizję.

Spróbuj swoich sił

<?php

require_once 'Document.php';

// Wczytaj dane wejściowe
$title = trim(fgets(STDIN));
$content = trim(fgets(STDIN));
$newContent = trim(fgets(STDIN));

// TODO: Utwórz obiekt Document z tytułem i treścią

// TODO: Sklonuj dokument, aby utworzyć nową wersję

// TODO: Zaktualizuj treść klonu, ustawiając ją na nowy ciąg znaków

// TODO: Wypisz cztery wiersze:
// 1. Wersja oryginalnego dokumentu
// 2. Wersja sklonowanego dokumentu
// 3. Treść oryginalnego dokumentu
// 4. Treść sklonowanego dokumentu

?>
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator PHP online