Webstack
Bejelentkezés

Elfelejtetted a jelszavad?

Nem vagy még tag? Kattints ide és regisztrálj most!

PHP Magic metódusok - különleges tagfüggények - 2.rész

PHP | tomizej  | 2013-02-05 03:08:47

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

címkék
Címkék: tutorial, php,

Hozzászólások

Hozzászóláshoz be kell jelentkezni!

Keress minket Facebookon
Ajánlások