En PHP 5 une copie d'objet est créée en utilisant le mot-clé clone (qui
fait appel à la méthode __clone() de l'objet, si elle a été
définie).
Pas de clonage avec PHP 4.
Le clonage avec PHP n’a vu le jour que depuis PHP 5.
Pour quoi le clonage d’un objet ?
Le clonge d’un objet est le fait de créer une copie de cet objet. Mais créer une copie d'un objet possédant exactement les mêmes propriétés n'est pas toujours le comportement que l'on souhaite.
Le clonage doit permettre de modifier cela afin que chacun des attributs du clone utilise sa propre instance.
Lorsque vous créez une copie vous pouvez vouloir créer une nouvelle copie de l’objet avec les mêmes propriétés mais que le nouvel objet contienne une ressource représentant la nouvelle copie.
En PHP 5 une copie d'objet est créée en utilisant le mot-clé clone (qui fait appel à la méthode __clone() de l'objet, si elle a été définie). La méthode __clone() d'un objet ne peut être appelée directement.
Le mot clé clone fonctionne comme le mot clé new, mais l'instance retournée est une référence sur une copie.
Syntaxe :
<?php $copie_d_objet = clone $objet; ?>
Lorsqu'un objet est cloné, PHP effectue une copie superficielle de toutes les propriétés de l'objet. Toutes les propriétés qui sont des références à d'autres variables demeureront des références.
Exemple :
Sélectionner le code
<pre>
<?php
class Personne {
private $nom;
private $prenom;
function Personne($nom, $prenom) {
$this->setNom($nom);
$this->setPrenom($prenom);
}
function setNom($nom) {
$this->nom = $nom;
}
function setPrenom($prenom) {
$this->prenom = $prenom;
}
function getNomPrenom() {
return($this->nom." ".$this->prenom);
}
}
// Instanciation de l'objet original
$personne = new Personne("DUBOIS", "Pierre");
// Clonage de l'objet
$clonePersonne = clone $personne;
$clonePersonne->setPrenom("Caen");
print_r($personne);
print_r($clonePersonne);
?>
</pre>
Ce qui affiche :
Personne Object
(
[nom:Personne:private] => DUBOIS
[prenom:Personne:private] => Pierre
)
Personne Object
(
[nom:Personne:private] => DUBOIS
[prenom:Personne:private] => Caen
)
Comme nous le voyons avec ces 2 personnes, Caen est le clone de Pierre: elles ont toutes les deux les mêmes caractéristiques (un nom et un prénom), mais ce sont 2 êtres indépendants. Ceci est démontré en modifiant le prénom du clone, ce qui ne modifie pas le prénom de l'original.
Une fois le clonage effectué, si une méthode __clone() est définie, la méthode __clone() du nouvel objet sera appelée pour permettre à chaque propriété qui doit l'être d'être modifiée. Comme le montre l’exemple suivant.
Exemple :
Sélectionner le code
<?php
// La ligne suivate permet d'afficher tout texte
// comme texte simple et non comme du HTML.
// C'est utile car nous utiliserons la fonction print_r
// (pour plus d'info voir la documentation PHP )
header("Content-type: text/plain");
class SubObject
{
static $instances = 0;
public $instance;
public function __construct() {
$this->instance = ++self::$instances;
}
public function __clone() {
$this->instance = ++self::$instances;
}
}
class MyCloneable
{
public $objet1;
public $objet2;
function __clone()
{
// Force la copie de this->object, sinon
// il pointera vers le même objet.
$this->object1 = clone $this->object1;
}
}
$obj = new MyCloneable();
$obj->object1 = new SubObject();
$obj->object2 = new SubObject();
$obj2 = clone $obj;
print("Objet original :\n");
print_r($obj);
print("Objet cloné :\n");
print_r($obj2);
?>
Ce qui affiche :
Objet original : MyCloneable Object ( [objet1] => [objet2] => [object1] => SubObject Object ( [instance] => 1 ) [object2] => SubObject Object ( [instance] => 2 ) ) Objet cloné : MyCloneable Object ( [objet1] => [objet2] => [object1] => SubObject Object ( [instance] => 3 ) [object2] => SubObject Object ( [instance] => 2 ) )
Voici un script de test écrit pour tester le comportement du clone quand j'ai deux tableaux avec des valeurs primitives dans ma classe
Sélectionner le code
<?php
// La ligne suivate permet d'afficher tout texte
// comme texte simple et non comme du HTML.
// C'est utile car nous utiliserons la fonction print_r
// (pour plus d'info voir la documentation PHP )
header("Content-type: text/plain");
class MaClasse {
private $monArray = array();
function metDansArray($var) {
array_push($this->monArray, $var);
}
//utilisation de geter pour accéder au paramètre privé
function getArray() {
return $this->monArray;
}
}
$monObjet = new MaClasse();
/*metre des valeurs dans monObjet l'objet d'origine de MaClasse*/
$monObjet->metDansArray('bleu');
$monObjet->metDansArray('orange');
// Clone de monObjet
$monObjetClone = clone $monObjet;
// modifiction de l'objet d'origine
$monObjet->metDansArray('rouge');
// modifiction de l'objet d'origine
$monObjetClone->metDansArray('vert');
//tester
print "objet d'origine :\n";
print_r($monObjet->getArray());
print "objet clone :\n";
print_r($monObjetClone->getArray());
?>
Ce qui affiche
objet d'origine :
Array
(
[0] => bleu
[1] => orange
[2] => rouge
)
objet clone :
Array
(
[0] => bleu
[1] => orange
[2] => vert
)
Livre numérique court pour comprendre la méthode secrète permettant d'obtenir des likes sans fin sur Facebook.
GAGNER DE L'ARGENT