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>
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
.