Se pare ca si PHP-ul, ca si alte limbaje de programare, are posibilitatile sale inutile (sau care cel putin par inutile) pe care poti incepe sa le folosesti cand te astepti mai putin. Unul dintre ele este serializarea obiectelor care a dus la construirea functiilor __sleep si __wakeup care, evident, controleaza serializarea si de-serializarea obiectului respectiv.
In primul rand, ce este serializarea?
Este o metoda de a stoca/trimite date care se “transformata” intr-un simplu string ce poate fi usor trimis/stocat. Partea interesanta a serializarii consta in faptul ca, dupa de-serializare (se foloseste functia unserialize), totul ramane intact: proprietati, valori, forma.
De exemplu:
<?php$a = array('a'=>2, 'b', 3=>'c', 8);echo '='.$a['3']; // se afiseaza =c$b = serialize($a); // se executa serializareaecho $b; // a:4:{s:1:"a";i:2;i:0;s:1:"b";i:3;s:1:"c";i:4;i:8;}$c = unserialize($b); // noul arrayecho '-'.$c['3']; // se afiseaza -c, ca si cum $c ar fi acum $a?>
Partea si mai interesanta este ca se pot serializa obiecte. Adica:
<?php
class someclass {
// avem ceva proprietati / variabile
protected $andvar2;
public $var1;
// un constructor
public function __construct($v, $a=1) {
$this->var1 = $v; $this->andvar2 = $a;
}
// si o functie care returneaza un string
public function anotherF() {
return ' RETURN '.($this->var1+$this->andvar2);
}
}
// avem un obiect initializat cu parametrii constructorului
$obj = new someclass(10, 2);
// se executa serializarea
$a = serialize($obj);
echo '$a = '.$a.'<br />';
// $a = O:9:"someclass":2:{s:10:"?*?andvar2";i:2;s:4:"var1";i:10;}
$b = unserialize($a); // se face de-serializarea
echo $b->anotherF(); // se apeleaza metoda
// si se afiseaza RETURN 12
?>
Care-i faza cu __sleep si __wakeup?
Pai, ele este doua functii magice… care scoate un iepure din palarie. De fapt… nu chiar.
Acum, vorbind serios, mie mi se par relativ inutile… dar banuiesc ca nu am avut nevoie de ele si d-asta.
class someclass {
// avem ceva proprietati / variabile
protected $andvar2;
public $var1;
// un constructor
public function __construct($v, $a=1) {
$this->var1 = $v;
$this->andvar2 = $a;
}
// si o functie care returneaza un string
// si adunarea celor doua proprietati
public function anotherF() {
return ' RETURN '.($this->var1+$this->andvar2);
}
public function __sleep() {
// inainte de serializare, proprietatea $this->var1 devine 31
$this->var1 = $this->var1+21;
// si este pasata catre noul obiect cu aceasta valoare
// se face afisarea variabilelor din clasa,
// care ar trebui returnate ca array
echo '<pre>';
print_r( array_keys(get_object_vars($this)) );
echo '</pre> Now it's time to sleep ';
// (1) daca facem return de array('var1')
// la unserialize, $this->andvar2 nu este cunoscut
# return array('var1');
// (2) daca facem return de array('var1', 'andvar2')
// atunci variabilele vor fi pasate catre noul obiect
return array('var1', 'andvar2');
}
public function __wakeup() {
echo '<br />[gata] m-am trezit si vreau sa fac ceva';
return 'nu conteaza ce returnez aici';
}
}
$obj = new someclass(10, 2);
$a = serialize($obj);
$b = unserialize($a);
// se apeleaza metoda, desi nu a fost pasata din __sleep
echo $b->anotherF(); // metodele raman oricum
echo '<br /><br />Acum VAR1 are valoarea '.$b->var1;
// vom stii ca var1 este 31
echo '<br /><br />Acum ANDVAR2 are valoarea '.$b->andvar2;
// Fatal error: Cannot access protected property
// se pastreaza incapsularea
Puteti da un copy/paste pentru a va convinge care-i ideea.
Spor la programat!