Atak klonów w PHP

Dzisiaj wieczor­kiem roz­pracowywałem sobie klonowanie obiek­tów w PHP. Dokład­nie zain­teresowała mnie metoda __clone(). W manualu PHP za dużo nie napisali, więc naskrobałem sobie krótki kod do prze­prowadzenia testów. Chodziło mi o to czy pod­czas wykonywania klonowania obiektu uruchamiany jest kon­struk­tor oraz czy można jakoś numerować klony (a co za tym idzie — “na gorąco” przy­pisywać polom sklonowanego obiektu jakieś war­to­ś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:

  • pod­czas 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 :-)
Printed from: http://spiechu.pl/2009/09/28/atak-klonow-w-php/ .
© 2010.

Leave a Reply