Méthodes magiques

Les noms de méthodes __construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state() __clone() et __debugInfo() 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.

Note: Toutes les méthodes magiques DOIVENT être déclarées en public

Attention

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()

public __sleep ( void ) : array
__wakeup ( void ) : void

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 
$dsn$username$password;
    
    public function 
__construct($dsn$username$password)
    {
        
$this->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();
    }
}
?>

__toString()

public __toString ( void ) : string

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.

Avertissement

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;
?>

L'exemple ci-dessus va afficher :

Bonjour

Il est important de noter qu'avant PHP 5.2.0, la méthode __toString() n'était appelée que si elle était directement combinée avec echo ou print. Depuis PHP 5.2.0, elle est appelée dans tous les contextes de chaîne de caractères (par exemple, dans printf() avec le modificateur %s), mais pas dans les contextes d'autres types (par exemple, avec le modificateur %d). Depuis PHP 5.2.0, convertir un objet sans la méthode __toString() en chaîne de caractères émettra une E_RECOVERABLE_ERROR.

__invoke()

__invoke ([ $... ] ) : mixed

La méthode __invoke() est appelée lorsqu'un script tente d'appeler un objet comme une fonction.

Note:

Cette fonctionnalité est disponible depuis PHP 5.3.0.

Exemple #3 Exemple avec __invoke()

<?php
class CallableClass
{
    public function 
__invoke($x)
    {
        
var_dump($x);
    }
}
$obj = new CallableClass;
$obj(5);
var_dump(is_callable($obj));
?>

L'exemple ci-dessus va afficher :

int(5)
bool(true)

__set_state()

static __set_state ( array $properties ) : object

Cette méthode statique est appelée pour les classes exportées par la fonction var_export() depuis PHP 5.1.0.

Le seul paramètre de cette méthode est un tableau contenant les propriétés exportées sous la forme array('propriété' => valeur, ...).

Exemple #4 Utilisation de __set_state() (depuis PHP 5.1.0)

<?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($atrue) . ';'); // $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"
}

Note: 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, de sorte que la réimportation de ces objets échouera, 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.

__debugInfo()

__debugInfo ( void ) : array

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.

Cette fonctionalité a été ajoutée en PHP 5.6.0.

Exemple #5 Utilisation de __debugInfo()

<?php
class {
    private 
$prop;

    public function 
__construct($val) {
        
$this->prop $val;
    }

    public function 
__debugInfo() {
        return [
            
'propSquared' => $this->prop ** 2,
        ];
    }
}

var_dump(new C(42));
?>

L'exemple ci-dessus va afficher :

object(C)#1 (1) {
  ["propSquared"]=>
  int(1764)
}