Maison > Article > développement back-end > PHP orienté objet - explication détaillée du clonage d'objet et de la méthode magique __clone()
Un gros inconvénient de la fonction orientée objet de PHP4 est qu'elle fait des objets sont traités comme un autre type de données, ce qui rend de nombreuses méthodes POO courantes inutilisables, telles que les modèles de conception. Ces méthodes reposent sur la transmission d'objets sous forme de références à d'autres méthodes de classe, plutôt que par valeur, ce qui est la pratique par défaut de PHP. Heureusement, PHP5 résout ce problème et désormais tous les objets sont traités comme des références par défaut. Cependant, étant donné que tous les objets sont traités comme des références plutôt que comme des valeurs, il est désormais plus difficile de copier des objets. Si vous essayez de copier un objet référencé, cela pointera uniquement vers l'adresse de l'objet d'origine. Pour résoudre le problème de copie, PHP fournit un moyen explicite de cloner un objet clone (mot-clé, pas une méthode).
Vous pouvez cloner l'objet en ajoutant le mot-clé clone devant l'objet, comme suit :
destinationObject = clone targetObject;
Cloner l'objet :
<?phpclass Person{ var $name; var $sex; var $age; function construct($name, $sex, $age){ $this->name = $name; $this->sex = $sex; $this->age = $age; } function say(){ echo "我的名字:" . $this->name . ",性别:" . $this->sex . ",年龄:" .$this->age . "<br />"; } }$person1 = new Person("张三三", "男", 23); $person2 = clone $person1; //使用clone关键字克隆/复制对象,创建一个对象的副本 $person3 = $person1; //这不是复制对象,而是为对象多复制出一个访问该对象的引用 $person1->say(); //调用原对象中的说话方式,打印原对象中的全部属性值 $person2->say(); //调用副本对象中的说话方式,打印克隆对象中的全部属性值 $person3->say(); //调用原对象中的说话方式,打印原对象中的全部属性值?>
Dans le programme ci-dessus, un total de deux objets sont créés, dont l'un est une copie clonée via le mot-clé clone. Deux objets peuvent être complètement indépendants, mais les valeurs de leurs membres et propriétés sont exactement les mêmes. Si vous devez réattribuer les valeurs initiales aux propriétés membres de l'objet de copie cloné lors du clonage, vous pouvez déclarer une méthode magique "clone()" dans la classe. Cette méthode est automatiquement appelée lorsque l'objet est cloné, vous pouvez donc réinitialiser la copie clonée via cette méthode. La méthode clone() ne nécessite aucun paramètre. Réécrivez le code dans l'exemple ci-dessus, ajoutez la méthode magique clone() à la classe et réinitialisez les propriétés du membre dans l'objet de copie.
<?phpclass Person{ var $name; var $sex; var $age; function construct($name, $sex, $age){ $this->name = $name; $this->sex = $sex; $this->age = $age; } function say(){ echo "我的名字:" . $this->name . ",性别:" . $this->sex . ",年龄:" .$this->age . "<br />"; } function clone(){ $this->name = "李四四"; //为副本对象中的name属性重新赋值 $this->age = 10; //为副本对象中的age属性重新赋值 } }$person1 = new Person("张三三", "男", 23); $person2 = clone $person1; //创建一个对象的副本,并自动调用类中的clone()方法 $person1->say(); //调用原对象中的说话方式,打印原对象中的全部属性值 $person2->say(); //调用副本对象中的说话方式,打印克隆对象中的全部属性值?>
Résultats en cours d'exécution :
我的名字:张三三,性别:男,年龄:23 我的名字:李四四,性别:男,年龄:10
Pour Pour un objet d'une classe, si vous utilisez l'"opérateur clone", un nouvel objet exactement le même que l'objet courant sera copié, et la méthode magique de la classe sera automatiquement appelée à cette fois : clone() (tant que la méthode existe dans la classe).
Pour implémenter une classe singleton, vous devez « désactiver le clonage » pour l'objet de cette classe singleton. En PHP, afin d'éviter que le clonage de l'objet de classe singleton ne brise la forme d'implémentation ci-dessus de la classe singleton, un clone vide privé (privé modifié) est généralement fourni pour cela. ()méthode.
Regardons d'abord l'effet de « Aucun clonage n'est interdit » :
<?php class SingetonBasic { private static $instance; //静态变量要私有化,防止类外修改 private function construct() { //构造函数私有化,类外不能直接新建对象} // private function clone() {} //在clone()前用private修饰,用来禁止克隆 public static function getInstance() { //公共的静态方法, public——外部的接口,static——不使用对象而是通过类名访问 if (!(self::$instance instanceof self)) { //私有静态变量$instance为空 self::$instance = new self(); //新建为自身的对象,并赋值给私有变量$instance } return self::$instance; //返回私有变量$instance} }$a = SingetonBasic::getInstance();$b = SingetonBasic::getInstance(); var_dump($a === $b); //结果为:boolean true a和b指向的是同一个对象$c = clone $a; var_dump($a === $c); //结果为:boolean false a和c指向的不是同一个对象?>
Le résultat de l'opération est
boolean trueboolean false
Nous « interdisons le traitement du clonage », c'est-à-dire supprimons le
commentaireprivate function clone() {} //在clone()前用private修饰,用来禁止克隆de la
ligne de code dans le code ci-dessus.
Le résultat en cours d'exécution est
boolean trueFatal error: Call to private SingetonBasic::clone()
Autrement dit, lors du clonage, clone() est automatiquement appelé, mais la méthode est modifiée en privé et ne peut pas être appelée directement depuis l'extérieur de la classe, ce qui entraîne une erreur.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!