Napisany lis-17-2008
funkcje magiczne
Pisząc kod jakiejkolwiek klasy w PHP, istnieje łatwa możliwość rozszerzenia jej funkcjonalności poprzez użycie metod magicznych. Jest to specjalny zestaw funkcji, których nazwa zawsze zaczyna się od __. Aby zrozumieć, jak wiele dają nam one możliwości omówimy je sobie po kolei. Zaczniemy od tych, które powinien znać każdy. Zapewne używaliście ich, nie zdając sobie sprawy, że należą do grona “magicznych”.
__construct() i __destruct()
Tak, zarówno konstruktor jak i destruktor są metodami magicznymi. Przypomnę tylko, iż __construct() jest wywoływany w momencie tworzenia instancji klasy, a __destruct() gdy obiekt jest niszczony (świadomie przez programistę lub automatycznie kiedy kończy się działanie skryptu). Zatem przykładowa klasa MagicFunctions:
class MagicFunctions {
public $first;
public $second;
public function __construct() {
$this->first = 13;
$this->second = 15;
echo 'Konstruktor';
}
public function __destruct () {
echo 'Destruktor';
}
}
Akcesory __set() i __get()
Funkcja [mixed] _get($property_name) jest wywoływana w momencie, gdy dostęp do właściwości $property_name jest niemożliwy (nie istnieje, lub modyfikator dostępu jest inny niż public). Funkcja [void] __set($property_name,$property_value) wywoływana jest w identycznych okolicznościach jak __get() i ustawia wartość właściwości $property_name na $property_value. I w ten prosty sposób tworzymy sobie akcesory dla naszej klasy. Przykład:
class MagicFunctions {
public $first;
public $second;
public function __get($name) {
echo 'Poszukujemy wlasciwosci: '.$name;
return 0;
}
public function __set($name,$value) {
echo 'Ustawiamy wlasciwosc '.$name.' na '.$value;
}
}
$obj = new MagicFunctions();
$zmienna = $obj->a; //wywolanie metody __get() zwroci 0
echo $zmienna;
$obj->a = 4; //wywolanie metody __set()
__isset() i __unset()
Funkcja [bool] __isset($property_name) jest wywoływana, gdy nie ma dostępu do właściwości $property_name i użyta została funkcja issset() lub empty(). Natomiast [void] __unset($property_name) jest wykonywana w identycznej sytuacji jak _isset() z tą różnicą, że użyto funkcji unset(). Obie metody są dostępne dopiero od wersji PHP 5.1.0! Przykład:
class MagicFunctions {
public $first;
public $second;
public function __isset($name) {
echo 'Sprawdzam czy istnieje wlasciwosc: '.$name;
return TRUE;
}
public function __unset($name) {
echo 'Chce usunac wlasciwosc: '.$name;
}
}
$obj = new MagicFunctions();
$zmienna = isset($obj->a); //wywolanie metody __isset() zwroci TRUE
var_dump($zmienna);
unset($obj->a) //wywolanie metody __unset()
__call() i __callStatic()
Funkcja [mixed] __call($method_name,$params) jest wykonywana, w sytuacji gdy dostęp do metody $method_name obiektu naszej klasy jest niemożliwy (modyfikatory protected lub private) lub metoda ta po prostu nie istnieje. Argument $params to parametry przekazane w wywołaniu $method_name. Analogicznie jest w przypadku __callStatic($method_name,$params), ale tutaj wywołanie jest statyczne. Uwaga, jest dostępna dopiero od wersji PHP 5.3 !! Prześledźmy to na przykładzie:
class MagicFunctions {
public $first;
public $second;
public static function __callStatic ($name,$params) {
echo 'Wywolales nieisniejaca statyczna metode: '.$name;
foreach ($params as $value)
echo $value;
return 0;
}
public function __call($name,$params) {
echo 'Wywolales nieisniejaca metode: '.$name;
foreach ($params as $value)
echo $value;
return 1;
}
}
$obj = new MagicFunctions();
$one = $obj->hello(1,2,3) ;//wywolanie metody __call() zwróci 0
$two = MagicFunctions::hello2(1); //wywolanie metody __callStatic() zwróci 1
echo $one.' - '.$two;
__clone() i __toString()
Funkcja [void] __clone() pozwala nam na szybkie utworzenie identycznej, aczkolwiek niezależnej kopii istniejącego obiektu klasy. Jest wywoływana, jeśli skorzystamy z słowa kluczowego clone. Dzięki [string] __toString() możemy zdecydować co się będzie działo, gdy użyjemy na obiekcie instrukcji takiej jak echo. Przykład:
class MagicFunctions {
public $first = 1;
public $second = 2;
public function __clone(){
// wszystkie pozostale wlasciwosci zostana skopiowane
// nowy obiekt otrzyma zawsze wartosc wlasciwosci first rowna 3000
$this->first = 3000;
}
public function __toString() {
$return = 'Wypisane obiektu: ';
foreach ($this as $key)
$return.= $key;
return $return;
}
}
$obj = new MagicFunctions();
$obj2 = clone $obj; //$obj2 jest niezalezna kopia $obj
var_dump ($obj);
var_dump ($obj2);
echo $obj; //wywolanie __toString()
__sleep() i __wakeup()
Jeżeli skorzystamy z funkcji serialize() na instancji naszej klasy, która posiada zaimplementowaną metodę [array] __sleep(), to zostanie ona wywołana i powinna zwrócić tablicę z nazwami właściwości, które mają podlegać serializacji. W przypadku użycia funkcji unserialize() wykonana zostanie funkcja [void] __wakeup(). Popatrzmy:
class MagicFunctions {
public $first;
public $second;
public function __sleep() {
echo 'Przed serializacja';
return array('first');
}
public function __wakeup() {
echo 'Po deserializacji';
}
}
$obj = new MagicFunctions();
$obj->first = 1;
$obj->second = 2;
$one = serialize($obj); //wywolanie __sleep()
$obj_after = unserialize($one); //wywolanie __wakeup()
var_dump($obj_after);
__invoke()
Metoda __invoke() udostępniono od wersji PHP 5.3. Jest wywoływana, gdy obiekt jest używany w kontekście funkcji. Przykład:
class A {
public function __invoke ($a) {
echo $a;
}
}
$obj = new A();
$obj(100);
__set_state()
Funkcja __set_state($array) wykonywana jest w sytuacji, gdy użyjemy funkcji var_export(). Jedyny parametr $array jest tablicą asocjacyjną zawierająca eksportowane właściwości w formie array(’wlasciwosc’=>’wartosc’…). Przykład:
class MagicFunctions {
public $first;
public $second;
public static function __set_state ($params) {
echo 'Eksport obiektu';
return 'Po eksporcie';
}
}
$obj = new MagicFunctions();
eval('$s ='.var_export($obj,TRUE).';');
echo $s;
__autoload()
Funkcja __autoload($classname) nie jest metodą klasy. Pozwala na dynamiczne dołączanie plików do skryptu, korzystając z parametru $classname. Przykład:
function __autoload($classname) {
include_once $classname . '.php';
}
$obj = new MojaKlasa(); //dolaczenie pliku MojaKlasa.php
I w ten sposób omówiliśmy sobie wszystkie metody magiczne.

W przypadku __autoload() jest bardzo fajna alternatywa - spl_autoload_register() - pozwala ona m. in. na posiadanie wielu funkcji ładujących, co pomaga integrować ze sobą różne projekty bez utrudniania sobie życia.
bardzo ciekawe, dzieki
__autoload działa bardzo wolno w porównaniu z include/require
[…] metody magiczne __callStatic() i __invoke() - dodatkowe informacje TUTAJ […]