Méthodes magiques
Les noms de méthodes __construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state() et __clone() sont magiques dans les classes PHP. Vous ne pouvez pas utiliser ces noms de méthodes dans vos classes, sauf si vous voulez implémenter le comportement associé à ces méthodes magiques.
PHP réserve tous les noms de fonctions commençant par un double souligné __ pour les méthodes magiques. Il est recommandé de ne pas utiliser de noms de fonctions commençant par __ sauf si vous voulez des fonctionnalités magiques documentées.
__sleep() et __wakeup()
La fonction serialize() vérifie si votre classe a une méthode
avec le nom magique __sleep().
Si c'est le cas, cette méthode sera exécutée avant toute linéarisation. Elle peut
nettoyer l'objet, et elle est supposée retourner un tableau avec les noms de toutes
les variables de l'objet qui doivent être linéarisées.
Si la méthode ne retourne rien, alors NULL
sera linéarisé, et une alerte de type
E_NOTICE
sera émise.
Note:
Il n'est pas possible pour __sleep() de retourner des noms de propriétés privées des classes parentes. Le faire résultera en une erreur de niveau
E_NOTICE
. À la place, vous devriez utiliser l'interface Serializable.
Le but avoué de __sleep() est de valider des données en attente ou d'effectuer des opérations de nettoyage. De plus, cette fonction est utile si vous avez de très gros objets qui n'ont pas besoin d'être sauvegardés en totalité.
Réciproquement, la fonction unserialize() vérifie la présence d'une méthode dont le nom est le nom magique __wakeup(). Si elle est présente, cette fonction peut reconstruire toute ressource que l'objet pourrait possèder.
Le but avoué de __wakeup() est de rétablir toute connexion de base de données qui aurait été perdue durant la linéarisation et d'effectuer des tâches de réinitialisation.
Exemple #1 Utilisation de sleep() et wakeup()
<?php class Connection { protected $link; private $server, $username, $password, $db; public function __construct($server, $username, $password, $db) { $this->server = $server; $this->username = $username; $this->password = $password; $this->db = $db; $this->connect(); } private function connect() { $this->link = mysql_connect($this->server, $this->username, $this->password); mysql_select_db($this->db, $this->link); } public function __sleep() { return array('server', 'username', 'password', 'db'); } public function __wakeup() { $this->connect(); } } ?>
__toString()
La méthode __toString() détermine comment l'objet
doit réagir lorsqu'il est traité comme une chaîne de caractères.
Par exemple, ce que echo $obj; affichera. Cette méthode doit
retourner une chaîne, sinon une erreur E_RECOVERABLE_ERROR
sera levée.
Vous ne pouvez pas lancer d'exception depuis la méthode __toString(). Si vous le tentez, une erreur fatale en résultera.
Exemple #2 Exemple simple
<?php // Déclaration d'une classe simple class ClasseTest { public $foo; public function __construct($foo) { $this->foo = $foo; } public function __toString() { return $this->foo; } } $class = new ClasseTest('Bonjour'); echo $class; ?>
<?php class CallableClass { public function __invoke($x) { var_dump($x); } } $obj = new CallableClass; $obj(5); var_dump(is_callable($obj)); ?>
<?php class A { public $var1; public $var2; public static function __set_state($an_array) // Depuis PHP 5.1.0 { $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', // )); var_dump($b); ?>
L'exemple ci-dessus va afficher :
object(A)#2 (2) { ["var1"]=> int(5) ["var2"]=> string(3) "foo" }