PHP 5 obsahuje zvláštní metody, které provádějí určitou speciální činnost, pro niž byly zvlášť navrženy. Mezi základní takové metody patří __destruct(), __clone() a __construct().

Destruktor __destruct()

Destruktor zprostředkovaný metodou __destruct() je přesným opakem konstruktoru __construct() (viz Základy OOP) a je volán při rušení objektu. Destruktor můžeme použít například pro uvolnění zdrojů z paměti nebo pro ukončení spojení s databází (viz příklad).

<?php 
  class DotazNaDatabazi{ 
    protected $hostitel; 
    protected $jmeno; 
    protected $heslo; 
    protected $databaze; 
    protected $spojeni; 
    public $dotaz; 
    public function __construct($hostitel, $jmeno, $heslo, $databaze){ 
      $this->hostitel = $hostitel; 
      $this->jmeno = $jmeno; 
      $this->heslo = $heslo; 
      $this->databaze = $databaze; 
      $this->spojeni = mysql_connect($this->hostitel, $this->jmeno, $this->heslo); 
      if(!$this->spojeni){ 
        echo 'Spojení s databází selhalo!'; 
      } 
      if(!mysql_select_db($this->databaze, $this->spojeni)){ 
        echo 'Nebylo možné vybrat databázi'; 
      } 
    } 

    public function dotaz($dotaz){ 
      $this->dotaz = mysql_query($dotaz, $this->spojeni); 
    } 

    public function vysledek(){ 
      return mysql_fetch_array($this->dotaz, $this->spojeni); 
    } 

    public function __destruct(){ 
      mysql_close($this->spojeni); 
    } 
  } 

  $dotaz_na_databazi = new DotazNaDatabazi('localhost', '', '', 'databaze'); 
  $dotaz_na_databazi->dotaz("SELECT * FROM kniha"); 
  while($radek = $dotaz_na_databazi->vysledek()){ 
    echo $radek[2].'
'; } ?>

Tento příklad bude fungovat a pro ukázku použití dobře poslouží, ovšem není vhodný pro použití v praxi. Destruktor je poslední metoda volaná instancí. Použití destruktoru není vždy nutné – i v našem příkladu by spojení s databází zaniklo samo.

Stejně jako u konstruktoru, i u destruktoru je možné volat destruktor rodiče v potomkovi třídy. Syntaxe je pak parent::__destruct().

Zbývá dodat, že umístění destruktoru v třídě vzhledem k jiným metodám nepodléhá žádným pravidlům. Destruktor může být tedy umístěn před konstruktorem!

Kopírování s __clone()

Při vytváření kopií použijeme metodu __clone(). Uvnitř metody můžeme používat všechny vlastnosti kopírované (nebo možná lépe klonované) třídy. Uvnitř kopírované třídy používáme normálně pseudoproměnnou $this. Klon vytváříme pomocí zápisu $klon = clone $instance;. Podívejte se na následující ukázku:

<?php 
  class Trida { 
    public static $pocitadlo = 0; 
    public $cislo; 
    public function __construct(){ 
      $this->cislo=self::$pocitadlo++; 
    } 

    public function __clone(){ 
      $this->cislo=self::$pocitadlo++; 
      echo 'Funkce volána'; 
    } 
  } 

// 1 příklad 
  $i = new Trida; 
  echo $i->cislo; 

// 2 příklad 
  $i = new Trida; 
  echo $i->cislo; 
  echo $i->cislo; 

// 3 příklad 
  $i2 = clone $i; 
  echo $i2->cislo; 

// 4 příklad 
  $i3 = clone $i2; 
  echo $i3->cislo; 

// 5 příklad 
  echo $i2->cislo; 

// 6 příklad 
  $i = $i3; 
  echo $i->cislo; 
?>

Jak uvedná třída pracuje? Jedná se o statické počítadlo – každé instanci třídy bude přiděleno jedinečné číslo (id), které chceme následně vypisovat v různých úpravách.

Výsledkem příkladu bude zápis 011Funkce volána2Funkce volána323.

Při první instanci konstruktor přiřazuje počáteční hodnotu 0, vypíše se tedy jen 0. V druhém příkladu se vypíše 11, protože je vytvořena nová instance a statická vlastnost byla zvýšena o jedničku.

Třetí příklad ukazuje vytvoření klonu (kopie) existující instance, přičemž statická vlastnost se opět navýší – za povšimnutí určitě stojí, že se nejdříve vypíše řetězec a až poté číslo. Je to způsobeno tím, že nejdříve byla volána metoda kopie, ta vypsala řetězec již při kopii instance a následně byl volán příkaz pro vypsání hodnoty statické vlastnosti.

Čtvrtý příklad opět zvýší hodnotu statické vlastnosti o 1, vypíše řetězec a statickou vlastnost. Pátý přiklad vypisuje hodnotu statické vlastnosti z dříve volané instance (pro ukázku, aby bylo jasno, že se nemění).

Poslední příklad ukazuje vytvoření nové reference na již existující instanci (není klonována ani nově vytvářena).

Pozn. red.: Zdůrazňujeme, že tento text se týká PHP 5.

1 Příspěvěk v diskuzi

Odpovědět