Maison > Article > développement back-end > Quelle est la différence entre la copie profonde et la copie superficielle en php
La différence entre la copie profonde et la copie superficielle en PHP : 1. La copie profonde est une copie complète lors de l'attribution d'une valeur, tandis que la copie superficielle n'est qu'une affectation de référence, ce qui équivaut à prendre un alias. 2. Si la copie profonde apporte des modifications à ; l'un d'eux, cela n'affectera pas l'autre, et des modifications superficielles de copie apportées à l'un affecteront l'autre.
L'environnement d'exploitation de ce tutoriel : système Windows 10, PHP version 7.1, ordinateur DELL G3
En PHP, lorsque = est attribué, l'objet ordinaire est une copie complète, mais pour l'objet, c'est une copie superficielle. En d’autres termes, l’affectation d’un objet est une affectation de référence. (Lorsqu'un objet est passé en paramètre, il est également passé par référence, qu'il y ait ou non une esperluette devant le paramètre lorsque la fonction est définie)
En php4, l'affectation = de l'objet consiste à implémenter un copie, ce qui pose de nombreux problèmes. Nous pouvons, sans le savoir, faire de nombreuses copies.
En PHP5, = affectation et transfert d'objets sont tous deux des références. Pour implémenter une copie, PHP fournit l'implémentation de la fonction clone.
Clone fait une copie complète. Mais lors du clonage, nous ne souhaitons peut-être pas copier tout le contenu de l'objet source, nous pouvons alors utiliser __clone pour fonctionner.
Dans __clone(), nous pouvons effectuer certaines opérations. Notez que ces opérations, c'est-à-dire que la fonction __clone opère sur l'objet de copie copié
<?php //普通对象赋值,深拷贝,完全值复制 $m = 1; $n = $m; $n = 2; echo $m;//值复制,对新对象的改变不会对m作出改变,输出 1.深拷贝 echo PHP_EOL; /*==================*/ //对象赋值,浅拷贝,引用赋值 class Test{ public $a=1; } $m = new Test(); $n = $m;//引用赋值 $m->a = 2;//修改m,n也随之改变 echo $n->a;//输出2,浅拷贝 echo PHP_EOL; ?>
Étant donné que l'objet est référencé lors de l'affectation, afin de réaliser la copie de valeur, PHP fournit la fonction clone pour copier l'objet.
Mais il y a un problème avec la fonction de clonage. Lorsqu'un objet est cloné, les attributs ordinaires de l'objet d'origine peuvent être copiés par valeur, mais lorsque les attributs de l'objet source sont attribués, ils le sont toujours par référence, qui est une copie superficielle.
<?php class Test{ public $a=1; } class TestOne{ public $b=1; public $obj; //包含了一个对象属性,clone时,它会是浅拷贝 public function __construct(){ $this->obj = new Test(); } } $m = new TestOne(); $n = $m;//这是完全的浅拷贝,无论普通属性还是对象属性 $p = clone $m; //普通属性实现了深拷贝,改变普通属性b,不会对源对象有影响 $p->b = 2; echo $m->b;//输出原来的1 echo PHP_EOL; //对象属性是浅拷贝,改变对象属性中的a,源对象m中的对象属性中a也改变 $p->obj->a = 3; echo $m->obj->a;//输出3,随新对象改变 ?>
Pour obtenir une véritable copie complète d'un objet, il existe deux méthodes :
Écrire la fonction clone : comme suit
<?php class Test{ public $a=1; } class TestOne{ public $b=1; public $obj; //包含了一个对象属性,clone时,它会是浅拷贝 public function __construct(){ $this->obj = new Test(); } //方法一:重写clone函数 public function __clone(){ $this->obj = clone $this->obj; } } $m = new TestOne(); $n = clone $m; $n->b = 2; echo $m->b;//输出原来的1 echo PHP_EOL; //可以看到,普通属性实现了深拷贝,改变普通属性b,不会对源对象有影响 //由于改写了clone函数,现在对象属性也实现了真正的深拷贝,对新对象的改变,不会影响源对象 $n->obj->a = 3; echo $m->obj->a;//输出1,不随新对象改变,还是保持了原来的属性 ?>
Il n'est pas pratique de réécrire la fonction __clone(), et vous devez mettre cette classe dans chaque classe Les attributs de l'objet sont tous clonés un par un dans __clone()
La deuxième méthode est implémentée par sérialisation et désérialisation. Cette méthode est simple pour réaliser la copie profonde de l'objet et n'a pas besoin de modifier la classe
<?php class Test{ public $a=1; } class TestOne{ public $b=1; public $obj; //包含了一个对象属性,clone时,它会是浅拷贝 public function __construct(){ $this->obj = new Test(); } } $m = new TestOne(); //方法二,序列化反序列化实现对象深拷贝 $n = serialize($m); $n = unserialize($n); $n->b = 2; echo $m->b;//输出原来的1 echo PHP_EOL; //可以看到,普通属性实现了深拷贝,改变普通属性b,不会对源对象有影响 $n->obj->a = 3; echo $m->obj->a;//输出1,不随新对象改变,还是保持了原来的属性,可以看到,序列化和反序列化可以实现对象的深拷贝 ?>
. Il existe aussi la troisième méthode. La méthode est en fait similaire à la deuxième, json_encode puis json_decode pour réaliser la mission
Apprentissage recommandé : "
Tutoriel vidéo PHP"
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!