20
Les objects ( instances des classes ) ne se comportent pas de la même façon que des tableaux ( array ) en PHP.
En effet, si on veut copier un tableau il nous suffit de l’assigner à une variable ( $b dans l’exemple ci-dessous). On peut modifier par la suite les données de ce nouveau tableau sans affecter les valeurs du tableau copié.
$a = array( 'x' => 5 ) ; $b = $a ; $b['x'] = 10 ; print_r($a); // affiche //Array ( [x] => 5 ) print_r($b); // affiche Array ( [x] => 10 )
Si on fait la même chose avec un objet on obtiens un résultat inattendu.
class Test{
public $a ;
}
$a = new Test;
$a->a = 10 ;
$b = $a ;
print_r( $a );
// affiche
Test Object
(
[a] => 10
)
print_r( $b );
// affiche
Test Object
(
[a] => 10
)
$b->a = 5 ;
print_r( $b );
// affiche
Test Object
(
[a] => 5
)
// jusqu'à là tout va bien. Mais...
print_r( $a );
// affiche
Test Object
(
[a] => 5
)
// uhhh... c'est pas ce que je voulais
En fait, lors d’une copie par assignation l’objet n’est pas réellement copié mais assigné comme référence. C’est à dire, les objets avec des noms différents ont le même contenu. Ou pour être plus exact, un contenu a des noms (noms des variables) différents. Du coup, si on change des valeurs d’un objet ($b dans notre exemple) on change automatiquement les valeurs de l’autre ( $a dans notre exemple). Voir la doc PHP pour plus d’info sur les références: http://fr2.php.net/manual/fr/language.references.php
On peut évidement faire une copie manuellement mais il existe en php un moyen plus simple. C’est le clônage. Pour faire le clônage d’un objet il faut ajouter dans notre class une méthode « magique » __clone(){} . Oui tout simplement: public function __clone(){} . En suite pour avoir une copie on appelle une espèce de fonction qui n’est pas vraiment une fonction mais un « mot-clé » clone.
class Test{
public $a ;
public function __clone(){}
}
$a = new Test;
$a->a = 10 ;
$b = clone $a ;
print_r( $a );
// affiche
Test Object
(
[a] => 10
)
print_r( $b );
// affiche
Test Object
(
[a] => 10
)
// bon ça on le savait déjà. Maintenant...
$b->a = 5 ;
print_r( $b );
// affiche
Test Object
(
[a] => 5
)
// et enfin ...
print_r( $a );
// affiche
Test Object
(
[a] => 10
)
// là c'est bon
Pour plus d’info sur le clônage :
http://fr2.php.net/manual/fr/language.oop5.cloning.php