Méthodes magiques Les méthodes magiques sont des méthodes spéciales qui écrasent l'action par défaut de PHP quand certaines actions sont réalisées sur un objet. Toutes les méthodes commençant par __ sont réservé par PHP. Ainsi, il n'est pas recommandé d'utiliser un tel nom de méthode sauf lors de l'écrasage du comportement de PHP. Les méthodes suivantes sont considérées magiques : __construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __serialize(), __unserialize(), __toString(), __invoke(), __set_state() __clone(), et __debugInfo(). Toutes les méthodes magiques, à l'exception de __construct(), __destruct(), et __clone(), doivent être déclaré en tant que public, sinon une E_WARNING est émise. Antérieur à PHP 8.0.0, aucun diagnostic n'était émis pour les méthodes magiques __sleep(), __wakeup(), __serialize(), __unserialize(), et __set_state(). Si des déclarations de types sont utilisé dans la définition d'une méthode magique, elles doivent être identique à la signature décrit dans ce document. Sinon, une erreur fatale est émise. Antérieur à PHP 8.0.0, aucun diagnostic n'était émis. Cependant, __construct() et __destruct() ne doivent pas déclarer un type de retour ; sinon une erreur fatale est émise. <link linkend="object.sleep">__sleep()</link> et <link linkend="object.wakeup">__wakeup()</link> public array__sleep public void__wakeup serialize vérifie si la 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. 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. Utilisez __serialize() à la place. 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 un objet très large n'a pas besoin d'être sauvegardés dans sa 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. Utilisation de sleep() et wakeup() dsn = $dsn; $this->username = $username; $this->password = $password; $this->connect(); } private function connect() { $this->link = new PDO($this->dsn, $this->username, $this->password); } public function __sleep() { return array('dsn', 'username', 'password'); } public function __wakeup() { $this->connect(); } } ?> ]]> <link linkend="object.serialize">__serialize()</link> et <link linkend="object.unserialize">__unserialize()</link> public array__serialize public void__unserialize arraydata serialize vérifie si la classe a une méthode avec le nom magique __serialize(). Si c'est le cas, cette méthode sera exécutée avant toute linéarisation. Elle doit construire et retourner un &array; associatif de paire clé/valeur qui représente la forme linéarisée de l'objet. Si aucun tableau n'est retournée une TypeError sera lancée. Si __serialize() et __sleep() sont tout les deux définie dans le même objet, alors seulement __serialize() sera appelé. __sleep() sera ignoré. Si l'objet implémente l'interface Serializable, la méthode serialize() de l'interface sera ignorée et __serialize() sera utilisé à la place. L'utilisation prévue de __serialize() est de définir une représentation arbitraire de l'objet pour le linéariser facilement. Les éléments du tableau peuvent correspondre aux propriétés de l'objet mais cei n'est pas requis. inversement, unserialize vérifie la présence d'une fonction avec le nom magique __unserialize(). Si présent, cette fonction sera passé le tableau restauré qui a été retournée depuis __serialize(). Il peut alors restaurer les propriétés de l'objet depuis ce tableau comme approprié. Si __unserialize() et __wakeup() sont tout les deux définie dans le même objet, alors seulement __unserialize() sera appelée. __wakeup() sera ignorée. Cette fonctionnalité est disponible à partir de PHP 7.4.0. Serialize et unserialize dsn = $dsn; $this->username = $username; $this->password = $password; $this->connect(); } private function connect() { $this->link = new PDO($this->dsn, $this->username, $this->password); } public function __serialize(): array { return [ 'dsn' => $this->dsn, 'user' => $this->username, 'pass' => $this->password, ]; } public function __unserialize(array $data): void { $this->dsn = $data['dsn']; $this->username = $data['user']; $this->password = $data['pass']; $this->connect(); } }?> ]]> <link linkend="object.tostring">__toString()</link> public string__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. À partir de PHP 8.0.0, la valeur de retour suit les sémantiques standard de PHP, signifiant que la valeur sera convertie en une string si possible et si le typage stricte est désactivé. À partir de PHP 8.0.0, toute classe qui contient une méthode __toString() implémente aussi implicitement l'interface Stringable, et passera donc les vérifications de types pour cette interface. Implémenter quand même explicitement l'interface est recommandé. En PHP 7.4, la valeur de retour doit être une string, sinon une Error est lancé. Antérieur à PHP 7.4.0, la valeur de retour doit être une string, sinon une E_RECOVERABLE_ERROR fatale est émise. Il était impossible de lancer une exception depuis la méthode __toString() antérieur à PHP 7.4.0. Cela entraînera une erreur fatale. Exemple simple foo = $foo; } public function __toString() { return $this->foo; } } $class = new ClasseTest('Bonjour'); echo $class; ?> ]]> &example.outputs; <link linkend="object.invoke">__invoke()</link> mixed__invoke values La méthode __invoke() est appelée lorsqu'un script tente d'appeler un objet comme une fonction. Exemple avec <link linkend="object.invoke">__invoke()</link> ]]> &example.outputs; <link linkend="object.set-state">__set_state()</link> static object__set_state arrayproperties Cette méthode statique est appelée pour les classes exportées par la fonction var_export. Le seul paramètre de cette méthode est un tableau contenant les propriétés exportées sous la forme ['property' => value, ...]. Utilisation de <link linkend="object.set-state">__set_state()</link> var1 = $an_array['var1']; $obj->var2 = $an_array['var2']; return $obj; } } $a = new A; $a->var1 = 5; $a->var2 = 'foo'; $b = var_export($a, true); var_dump($b); eval('$c = ' . $b . ';'); var_dump($c); ?> ]]> &example.outputs; 5, 'var2' => 'foo', ))" object(A)#2 (2) { ["var1"]=> int(5) ["var2"]=> string(3) "foo" } ]]> Lors de l'exportation d'un objet, var_export ne vérifie pas si __set_state() est implémenté par la classe de l'objet, ainsi la réimportation d'objets résultera en une exception Error, si __set_state() n'est pas implémenté. En particulier, cela affecte certaines classes internes. Il est de la responsabilité du programmeur de vérifier que seuls les objets dont la classe implémente __set_state() seront ré-importés. <link linkend="object.debuginfo">__debugInfo()</link> array__debugInfo Cette méthode est appelée par var_dump lors du traitement d'un objet pour récupérer les propriétés qui doivent être affichées. Si la méthode n'est pas définie dans un objet, alors toutes les propriétés publiques, protégées et privées seront affichées. Utilisation de <link linkend="object.debuginfo">__debugInfo()</link> prop = $val; } public function __debugInfo() { return [ 'propSquared' => $this->prop ** 2, ]; } } var_dump(new C(42)); ?> ]]> &example.outputs; int(1764) } ]]>