PHP Magic metódusok - különleges tagfüggények - 2.rész
Ebben a cikkben megvizsgáljuk hogyan archiválhatunk objekumokat, klónozhatunk, vagy másolhatunk példányokat. A következő magic metódusokról lesz szó: __toString(), __invoke(), __set_state() és __clone().
Ha ezeket még újnak találod, akkor olvasd el egy korábbi cikkünket a témról: PHP Magic metódusok avagy különleges tagfüggények - 1.rész
Objektumok szöveges reprezentációja
Néhány esetben szükséges lehet, hogy az objektumokat szöveges (string) formára hozzuk. A PHP alapjába véve nem engedi meg az objektumok típuskényszerítését string típusra. Elkapható Fatal Error kivételt dob, ha megtesszük. Akkor viszont nem, ha egy Magic metódussal kiváltjuk az eseményt.
__toString()
A __toString()
metódus akkor hívódik meg, ha egy objektumot string típusra szeretnénk konvertálni. Pl.: egyszerűen átadjuk az echo
függvénynek az objektumot. echo $obj
;
Jó lehet, ha az objektum pillanatnyi állapot szeretnénk formázott módon megjeleníteni.
class Human { public $name; public $age; public function __construct($name) { $this->name = $name; } public function __toString() { echo "En vagyok {$this->name}, {$this->age} éves vagyok. \n"; } } $pali = new Human('Pali'); $pali->age = 23; echo $pali;
__set_state()
A __set_state()
metódus egy statikus metódus. Akkor kerül meghívásra, ha egy objektumra meghívjuk a var_export()
függvényt (PHP 5.1.0. –tól).
A var_export()
annyiban tér el a var_dump()
-tól, hogy ez egy valid PHP reprezentációt ad vissza, amit egy eval()
függvénnyel parsolhatunk.
Hogy mit érdemes írni a __set_state()
metódusban. Igazából ez a programozón múlik. Talán a legjobb gyakorlat, ha próbáljuk visszaadni az aktuális objektum akkori állapotával. A fejlesztőre van bízva, mi történjen az objektum exportálásakor. Ha használunk valamilyen profilert, vagy debug eszközöket, melyek valószínű, hogy exportálni fognak objektumokat, mindenképp elengedhetetlen a használatuk.
Nézzünk néhány példát a használatára:
Ha az alábbi kódot lefuttatjuk, a var_exort() által kiírt kód parsolásával, a __set_state statikus metódust hívnánk meg. Így FATAL ERROR
-t kapunk:
class Human { public $name; public $age; public function __construct($name) { $this->name = $name; } } $zoli = new Human("Zoli"); eval('$b='.var_export($zoli, 1).';'); var_dump($b);
Viszont ha implementáljuk a __set_state()
metódust beállíthatjuk az objektum állapotát, így exportálható lesz.
/.. public static function __set_state(array $array) { return new self($array['name']); } /..
Objektumok klónozása (másolása)
Az objektumok referencia típusú változók. Így két féle másolhatóak: deep copy, shallow copy.
Az objektum másolás módszereiről és gyakorlati példákról az Objektumok klónozása cikkben foglalkozunk részletesebben (később).
Fontos, hogy az objektumok klónozása során a becsomagolt osztályok csak sekély másolva lesznek (csak referencia lesz másolva!) Ezt a problémát ki tudjuk küszöbölni a __clone()
magic metódussal.
__clone()
A __clone()
metódus akkor hívódik meg, ha egy objektumot klónozunk (clone
kulcsszó). Nincs paramétere és visszatérési értéke sem.
Ebben a metódusban védekezhetünk a másolás ellen, illetve a gondoskodhatunk arról, hogy a becsomagolt objektumok is mély másolással (deep copy) legyenek másolva.
Példa egy másolás védett objektum létrehozására:
class Driver { public $name; public function __clone() { throw new Exception("Az objektum nem másolható"); } } $zoli = new Driver('Zoli'); $zoliMasolat = clone $zoli;
Hívható objektumok
PHP 5.3-tól létezik egy nyelvi kiegészítés, amellyel objektumokat meghívhatunk függvényként, mintha az objektumot tartalmazó változó egy függvény referencia lenne.
__invoke()
Ha az alábbi kódot lefuttatjuk FATAL ERROR
-t kapunk:
class Car { protected $type; } $car = new Car(); $car('start');
Ha implementáljuk az __invoke()
metódust, alapértelmezetten ez fog meghívódni:
class Car { protected $type; public function __invoke($args) { echo "Az autó {$args}"; } } $car = new Car(); $car('lindul');
Kimenet: Az autó elindul.
Konklúzió
A PHP magic metódosok kibővítik az objektumosztályok funkcionalitását. Olyan speciális viselkedésekre vehetjük rá őket, amiket ezek nélkül nem lehetne megoldani. OOP-t támogató fejlesztőknek mindenképp érdemes ismerni ezeket a lehetőségeket.
Szerző: tomizej
Hozzászóláshoz be kell jelentkezni!
Hozzászólások