Atak klonów w PHP

Dzisiaj wieczor­kiem rozpra­co­wy­wa­łem sobie klono­wa­nie obiek­tów w PHP. Dokład­nie zain­te­re­so­wała mnie metoda __clone(). W manu­alu PHP za dużo nie napi­sali, więc naskro­ba­łem sobie krótki kod do prze­pro­wa­dze­nia testów. Chodziło mi o to czy podczas wyko­ny­wa­nia klono­wa­nia obiektu urucha­miany jest konstruk­tor oraz czy można jakoś nume­ro­wać klony (a co za tym idzie — „na gorąco” przy­pi­sy­wać polom sklo­no­wa­nego 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 />';
?>

Urucho­mie­nie kodu wyświe­tli:
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

Wnio­ski:

  • podczas klono­wa­nia nie jest urucha­miany konstruktor,
  • metoda __clone() wywo­ły­wana jest po sklo­no­wa­niu obiektu, a zmie­nia­jąc coś poprzez $this->cośTam operu­jemy już na klonie!
  • prywatne zmienne statyczne to fajna zabawa :-)
Printed from: http://spiechu.pl/2009/09/28/atak-klonow-w-php/ .
© 2010.

Skomentuj