PHP 5 aduce un nou model al programării orientate pe obiect cu o multitudine de îmbunatăţiri şi facilităţi, spre bucuria programatorilor deja obişnuiţi cu pseudo-modelul din PHP 4. O facilitate care poate ajuta în cazul unor proiecte cu module interconectabile, este cea numită metode magice. Acestea sunt un set de metode standard, rezervate în limbajul de programare, care au o aceeaşi semnificaţie şi o aceeşi funcţionalitate în cazul oricăror clase definite de utilizator. Aceşte metode sunt autoapelate în anumite condiţii sau în cazul unor acţiuni externe.

Constructor si destructor

Metodele __construct() şi __destruct(), deşi pot fi numite magice doar prin modul de scriere, ele făcând parte din teoria programării orientate pe obiect, sunt metodele care se vor apela automat la crearea (instanţierea) respectiv distrugerea unui obiect aparţinând unei clase. De regula, în constructor se crează conexiuni, se setează variabile, se preiau variabile externe sau orice altă acţiune de iniţializare a elementelor clasei, pe când în destructor se face curăţenie printre aceste elemente, se închid eventualele conexiuni sau se şterg fişiere.


class math
{
protected $a;
protected $b;

public function __construct($x, $y)
{
$this->a = $x;
$this->b = $y;
}

public function add()
{
return $this->a + $this->b;
}

public function multiply()
{
return $this->a * $this->b;
}

public function __destruct()
{
unset($this->a);
unset($this->b);
}
}

$math = new math(3, 8);
echo $math->add();
unset($math);
?>

Constructorul va fi astfel apelat în momentul creării obiectului folosind operatorul new iar destructorul va fi apelat în la apelul lui unset() asupra obiectului în mod expicit sau în mod implicit la terminarea execuţiei scriptului, daca nu s-a făcut altfel.

Serializare şi deserializare

Serializarea este procesul de a liniariza o variabilă de orice tip într-una de tip string, cu scopul de a pastra informaţiile din interiorul ei(precum si tipul/tipurile de date) şi pentru a le transmite la distanţă fără pierdere de informaţii. Deserializarea este, evident, procesul invers. Daca în cazul unui vector rezultatul serializării este un string ce conţine în ordine şi pe nivele elementele acestuia, în cazul claselor se oferă posibilitatea de a alege ce date să se pastreze sau să se porteze. Pentru acest lucru au fost create două metode magice care vor fi apelate automat la apelul serializării sau a deserializării: __sleep() şi __wakeup().


class math
{
protected $a;
protected $b;

public function __construct($x, $y)
{
$this->a = $x;
$this->b = $y;
}

public function add()
{
return $this->a + $this->b;
}

public function multiply()
{
return $this->a * $this->b;
}

public function __sleep()
{
return array('a', 'b');
}

public function __wakeup()
{
echo 'a=' . $this->a . '; b=' . $this->b;
}

public function __destruct()
{
unset($this->a);
unset($this->b);
}
}

$mathAdd = new math(3, 8);
echo $mathAdd->add(); /* va afisa 11 */
$tmpData = serialize($mathAdd);

$mathMultiply = new math(0, 0);
$mathMultiply = unserialize($tmpData);
echo $math->multiply(); /* va afisa 24 */
?>

De menţionat este că la apelul unserialize() şi implicit a lui math::__wakeup() scriptul va printa valorile primite de la prima instanţiere a clasei.

String

Există şi o metodă simplă, numită __toString() care va fi apelată la fiecare apel al lui echo, print sau încercare de folosire a obiectului ca un string.


class hello
{
protected $foo;

public function __construct($bar)
{
$this->foo = $bar;
}

public function __toString()
{
return "Hello " . $this->foo;
}
}

$hi = new hello('george');
echo $hi; /* va tipari "Hello george" */

?>

O altă metodă de transmitere a datelor între obiecte, posibil mai convenabilă decât serializarea şi deserializarea, poate fi făcută cu ajutorul funcţiei var_export() şi a metodei magice __set_state(). var_export() va returna un string care va conţine, fie valoarea numerica (în cazul variabilelor scalare de tip numeric), fie o valoare de tip string (cazul variabilelor string), fie stringul care ar crea un vector în cazul acestora, fie valoarea returnată de metoda magica __set_state() în cazul obiectelor. Această metodă magică a fost introdusă odată cu versiunea 5.1.0 a PHP.


class A
{
public $var1;
public $var2;

public static function __set_state($an_array)
{
$obj = new A;
$obj->var1 = $an_array['var1'];
$obj->var2 = $an_array['var2'];
return $obj;
}
}

$a = new A;
$a->var1 = 5;
$a->var2 = 'foo';

eval('$b = ' . var_export($a, true) . ';');
// $b = A::__set_state(array(
// 'var1' => 5,
// 'var2' => 'foo',
// ));

?>

Autoîncărcarea

Deşi nu este o metodă, funcţia __autoload() poate fi de mare ajutor atunci când aplicaţia dispune de un numar considerabil de clase care nu sunt folosite toate în acelaşi timp. Astfel, aceasă funcţie se va apela şi va include, dacă este nevoie, un fişier care va conţine definiţia clasei, în momentul instanţierii unui obiect. În scenariul de faţă, este de preferat ca toate definiţiile clasei să fie situate într-un acelaşi director, iar fiecare clasă situată într-un fişier separat al cărui nume sa fie identic cu al clasei.


function __autoload($className)
{
if (!class_exists($className))
{
include("includes/classes/" . $className . ".php");
}
}

Se evită in acest fel încărcarea tuturor claselor existente în aplicaţie şi îngreunarea acesteia luând în considerare presupunerea ca nu toate clasele vor fi folosite în oricare acţiune a aplicaţiei, prin faptul ca o clasa va fi încarcată doar dacă este nevoie si doar atunci când este nevoie.