Metody magiczne w PHP – część trzecia i ostatnia

Nadszedł czas na ostatnią część cyklu opisującego metody magiczne w PHP. W części pierwszej oraz drugiej omówiłem wiele z nich: konstruktor i destruktor, settery, gettery, metody zwiększające możliwości serializacji obiektów oraz klonowania. W niniejszym tekście przedstawię pozostałe metody magiczne: __callStatic(), __isset(), __unset(), __invoke() oraz __set_state().

Metoda __callStatic()

Metoda ta pojawiła się stosunkowo niedawno, bo dopiero w PHP 5.3. Jest bardzo podobna do omawianej w poprzedniej części zestawienia metody __call(). Tak jak ona jest używania w momencie wywołania nieistniejącej metody, jednak tylko w przypadku, gdy nastąpiło to w sposób statyczny (tak też musi być sama zdefiniowana). Jako parametry __callStatic() przyjmuje kolejno nazwę wywołanej metody oraz tablicę zawierającą przekazane do niej parametry. Na poniższym przykładzie widać porównanie obu metod:

class TestCall
{
	public function __call($nazwa, $argumenty)
	{
		echo "Wywołano metodę $nazwa z parametrami: " . implode(',', $argumenty) . PHP_EOL;
	}

	public static function __callStatic($nazwa, $argumenty)
	{
		echo "Wywołano statycznie metodę $nazwa z parametrami: " . implode(',', $argumenty) . PHP_EOL;
	}
}
$obj = new TestCall();
$obj->nieistniejacaMetoda('normalne wywołanie');
TestCall::nieistniejacaMetoda('statyczne wywołanie');

Wynik działania powyższego skryptu będzie następujący:

Wywołano metodę nieistniejacaMetoda z parametrami: normalne wywołanie 
Wywołano statycznie metodę nieistniejacaMetoda z parametrami: statyczne wywołanie 

Metody __isset() oraz __unset()

Pierwsza jest wywoływana w momencie, gdy pojawia się próba dostępu do nieistniejącej właściwości obiektu poprzez funkcję isset() lub empty(). Metoda __unset() jest natomiast wywoływana podczas  wykonywania funkcji unset() na nieistniejącej właściwości. Obie przyjmują jako parametr nazwę wywołanej właściwości. Poniższy przykład obrazuje sposób działania opisanych metod:

class TestowaKlasa
{
   public function __unset($nazwa)
   {
      echo "Nie można usunąć '$nazwa', zmienna nie isnieje!" . PHP_EOL;
   }

   public function __isset($nazwa){
      echo "Właściwość '$nazwa' nie istnieje!" . PHP_EOL;
   }
}

$obj = new TestowaKlasa();

unset($obj->nieistniejacaWlasciwosc);
isset($obj->nieistniejacaWlasciwosc);

Efekt działania będzie następujący:

Nie można usunąć 'nieistniejacaWlasciwosc', zmienna nie isnieje!
Właściwość 'nieistniejacaWlasciwosc' nie istnieje!

Metoda __invoke()

Została wprowadzona w PHP 5.3 i jest wywołana w momencie, gdy następuje próba użycia obiektu w sposób przeznaczony dla funkcji. Poszczególne parametry odpowiadają tym użytym w wywołaniu obiektu. Warto pamiętać, że gdy klasa posiada zdefiniowaną metodę __invoke(), zastosowanie na jej obiekcie funkcji is_callable() zwróci w rezultacie true.

class MojaKlasa 
{
   public function __invoke($parametr1, $parametr2)
   {
      var_dump($parametr1, $parametr2);		
   }	
}

$obj = new MojaKlasa();
$obj('abc', 123);
var_dump(is_callable($obj));

Wynik działania powyższego skryptu będzie następujący:

string(3) "abc"
int(123)
bool(true)

Metoda __set_state()

Jest to metoda statyczna, która jest wywoływana w momencie użycia na klasie funkcji var_export(). Przyjmuje jeden parametr, zawierający eksportowane właściwości w formacie: array('wlasciwosc1' => wartosc, 'wlasciwosc2' => wartosc, …). Obrazuje to przykład zaczerpnięty z dokumentacji:

class MojaKlasa
{
    public $w1;
    public $w2;

    public static function __set_state($tab)
    {
        $obj = new MojaKlasa();
        $obj->w1 = $tab['w1'];
        $obj->w2 = $tab['w2'];
        return $obj;
    }
}

$obj = new MojaKlasa();
$obj->w1 = 123;
$obj->w2 = 'abc';

eval('$b = ' . var_export($obj, true) . ';'); 
var_dump($b);
object(MojaKlasa)#2 (2) {
  ["w1"]=>
  int(123)
  ["w2"]=>
  string(3) "abc"
}

Podsumowanie

To była ostatnia część z cyklu „Metody magiczne w PHP”. W poszczególnych artykułach omówiłem wszystkie, jakie występują w PHP 5.3. Mam nadzieję, że wyjaśniły one mechanizmy, które mogą być bardzo przydatne w programowaniu obiektowym.

Jeden Komentarz

Dodaj komentarz