Le clonage d’objets et la méthode magique PHP __clone()

Dans la leçon précédente, on a vu que nos variables objets stockaient en fait des identifiants d’objets servant à accéder aux objets.

Lorsqu’on instancie une fois une classe, on crée un objet et on stocke généralement un identifiant d’objet dans une variable qu’on appelle une variable objet ou un objet par simplification.

Si on assigne le contenu de notre variable objet dans une nouvelle variable, on ne va créer qu’une copie de l’identifiant qui va continuer à pointer vers le même objet.

Cependant, dans certains cas, on voudra plutôt créer une copie d’un objet en soi. C’est exactement ce que va nous permettre de réaliser le clonage d’objet que nous allons étudier dans cette nouvelle leçon.

 

Les principes du clonage d’objets

Parfois, on voudra « copier » un objet afin de manipuler une copie indépendante plutôt que l’objet original.

Dans ces cas-là, on va « cloner » l’objet. Pour cela, on va utiliser le mot clef clone qui va faire appel à la méthode magique __clone() de l’objet si celle-ci a été définie. Notez qu’on ne peut pas directement appeler la méthode __clone().

Lorsque l’on clone un objet, le PHP va en fait réaliser une copie « superficielle » de toutes les propriétés relatives à l’objet, ce qui signifie que les propriétés qui sont des références à d’autres variables (objets) demeureront des références.

Dès que le clonage d’objet a été effectué, la méthode __clone() du nouvel objet (le clone) va être automatiquement appelée. Cela va généralement nous permettre de mettre à jour les propriétés souhaitées.

 

Exemple de clonage d’objets

Pour cloner un objet en pratique nous allons simplement devoir utiliser le mot clef clone et éventuellement pouvoir définir une méthode __clone() qui va nous permettre de mettre à jour les éléments du clone par rapport à l’original.

<!DOCTYPE html>
<html>
    <head>
        <title>Cours PHP & MySQL</title>
        <meta charset="utf-8">
        <link rel="stylesheet" href="cours.css">
    </head>
    
    <body>
        <h1>Titre principal</h1>
        <?php
            class Utilisateur{
                protected $nom;
                
                public function __construct($n){
                    $this->nom = $n;
                }
                
                public function __clone(){
                    $this->nom = $this->nom. ' (clone)';
                }
                public function getNom(){
                    echo $this->nom;
                }
            }

            $pierre = new Utilisateur('Pierre');
            $victor = clone $pierre;
            
            var_dump($pierre);
            echo '<br>';
            var_dump($victor);
            echo '<br>';
            $pierre->getNom();
            echo '<br>';
            $victor->getNom(); 
            
        ?>
        <p>Un paragraphe</p>
    </body>
</html>

 

Exemple de clonage d'objets avec la méthode magique __clone en PHP

On crée ici une classe qu’on appelle à Utilisateur. Cette classe possède une propriété $nom, un constructeur dont le rôle est d’assigner une valeur à $nom pour l’objet courant, une méthode getNom() qui sert à renvoyer la valeur de $nom de l’objet courant et finalement une méthode __clone().

Le rôle de la méthode __clone() est ici de modifier la valeur stockée dans $nom pour le clone en lui ajoutant « (clone) ».

On instancie ensuite notre classe et on assigne le résultat à une variable objet $pierre qu’on va cloner grâce au mot clef clone.

Lors du clonage, notre clone $victor va recevoir une copie superficielle des propriétés et des méthodes de l’objet de départ. Dès que le clonage est terminé, la méthode __clone() est appelée et va ici mettre à jour la valeur de la propriété $nom pour notre clone.

On voit bien ici qu’on a créé une copie indépendante de l’objet de départ (et donc une nouvelle instance de la classe) et qu’on ne s’est pas contenté de créer une copie d’un identifiant pointant vers le même objet dès qu’on affiche le contenu de nos deux objets et qu’on tente d’accéder à la valeur de leur propriété $nom.

Laisser un commentaire