Dzisiaj wieczorkiem rozpracowywałem sobie klonowanie obiektów w PHP. Dokładnie zainteresowała mnie metoda __clone(). W manualu PHP za dużo nie napisali, więc naskrobałem sobie krótki kod do przeprowadzenia testów. Chodziło mi o to czy podczas wykonywania klonowania obiektu uruchamiany jest konstruktor oraz czy można jakoś numerować klony (a co za tym idzie — “na gorąco” przypisywać polom sklonowanego obiektu jakieś wartości). Poniżej podaję kod z komentarzem.
<?php
class Klon {
// Ogolna liczba klonow
private static $liczbaKlonow = 0;
// Nr konkretnego klona
private $klonNr;
public function __construct() {
// Na etapie konstruktora przypisujemy polu klonNr wartość 0,
// jako iż nie jest żadnym klonem
$this->klonNr = 0;
// Dodatkowo wywalamy na ekran komunikat upewniający nas, że uruchomiono konstruktor
echo 'Uruchomiono konstruktor i stworzono obiekt Klon!<br />';
}
public function __clone() {
// Zwiększamy licznik liczby wszystkich klonów
self::$liczbaKlonow += 1;
// Przypisujemy aktualną wartość licznika nowo utworzonemu klonowi
$this->klonNr = self::$liczbaKlonow;
}
// Proste sprawdzenie czy obiekt jest klonem, a jeżeli tak to którym
public function getKlonNr() {
if ($this->klonNr == 0) return 'nie jest klonem';
return 'jest ' . $this->klonNr . ' klonem';
}
// Zwrócenie liczby wszystkich klonów obiektu
public function getLiczbaKlonow() {
return self::$liczbaKlonow;
}
}
$oryg = new Klon();
// Klonujemy "oryginalny" obiekt
$klon1 = clone $oryg;
$klon2 = clone $oryg;
// Klonujemy klon
$klon3 = clone $klon2;
// Wypisujemy "kto jest kim"
echo 'Zmienna $oryg ' . $oryg->getKlonNr() . '<br />';
echo 'Zmienna $klon1 ' . $klon1->getKlonNr() . '<br />';
echo 'Zmienna $klon2 ' . $klon2->getKlonNr() . '<br />';
echo 'Zmienna $klon3 ' . $klon3->getKlonNr() . '<br />';
echo 'Wszystkich klonow: ' . $oryg->getLiczbaKlonow() . '<br />';
?>
Uruchomienie kodu wyświetli:
Uruchomiono konstruktor i stworzono obiekt Klon!
Zmienna $oryg nie jest klonem
Zmienna $klon1 jest 1 klonem
Zmienna $klon2 jest 2 klonem
Zmienna $klon3 jest 3 klonem
Wszystkich klonow: 3
Wnioski:
- podczas klonowania nie jest uruchamiany konstruktor,
- metoda __clone() wywoływana jest po sklonowaniu obiektu, a zmieniając coś poprzez $this->cośTam operujemy już na klonie!
- prywatne zmienne statyczne to fajna zabawa
