Rumah >pembangunan bahagian belakang >masalah PHP >Apakah perbezaan antara salinan dalam dan salinan cetek dalam php
Perbezaan antara salinan dalam dan salinan cetek dalam PHP: 1. Salinan dalam adalah salinan lengkap apabila memberikan nilai, manakala salinan cetek hanyalah tugasan rujukan, yang bersamaan dengan mengambil alias 2. Jika mendalam salinan membuat Perubahan tidak akan menjejaskan yang lain, manakala pengubahsuaian salinan cetek kepada satu akan menjejaskan yang lain.
Persekitaran pengendalian tutorial ini: sistem Windows 10, versi PHP 7.1, komputer DELL G3
Mula-mula mari kita bercakap tentang pemahaman popular salinan dalam dan salinan cetek
Salinan dalam: nilai semasa tugasan disalin sepenuhnya, salinan lengkap dan perubahan kepada salah satu daripadanya tidak akan menjejaskan yang lain
Salinan cetek: Apabila memberikan, tugasan rujukan adalah bersamaan dengan mengambil alias. Mengubah suai salah satu daripadanya akan mempengaruhi yang lain
Dalam PHP, apabila = ditetapkan, objek biasa ialah salinan dalam, tetapi untuk objek, ia adalah salinan cetek. Dengan kata lain, tugasan objek adalah tugasan rujukan. (Apabila objek diluluskan sebagai parameter, ia juga diluluskan melalui rujukan, tidak kira sama ada terdapat ampersand di hadapan parameter apabila fungsi ditakrifkan)
Dalam php4, tugasan = objek adalah untuk melaksanakan salinan, yang mempunyai banyak masalah. Kami mungkin membuat banyak salinan.
Dalam PHP5, tugasan = dan pemindahan objek adalah kedua-dua rujukan. Untuk melaksanakan salinan, PHP menyediakan pelaksanaan fungsi klon.
Klon membuat salinan lengkap. Tetapi apabila mengklon, kita mungkin tidak mahu menyalin semua kandungan objek sumber, maka kita boleh menggunakan __clone untuk beroperasi.
Dalam __clone(), kita boleh melakukan beberapa operasi. Ambil perhatian bahawa operasi ini, iaitu, fungsi __clone beroperasi pada objek salinan yang disalin
<?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; ?>
Memandangkan objek dirujuk semasa tugasan, untuk mencapai penyalinan nilai, PHP menyediakan fungsi klon untuk menyalin objek .
Tetapi terdapat masalah dengan fungsi klon Apabila objek diklon, atribut biasa objek asal boleh disalin mengikut nilai, tetapi apabila atribut objek objek sumber ditetapkan, ia masih kekal. tugasan rujukan dan salinan cetek.
<?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,随新对象改变 ?>
Untuk mencapai salinan dalam sebenar objek, terdapat dua kaedah:
Tulis fungsi klon: seperti berikut
<?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,不随新对象改变,还是保持了原来的属性 ?>
Tulis semula __klon( ) fungsi Ia tidak begitu mudah, dan anda perlu meletakkan semua atribut objek dalam kelas ini dalam __clone() dalam setiap kelas - klon
Kaedah kedua ialah menggunakan bersiri dan penyahserilan untuk mencapai kaedah ini adalah mudah untuk merealisasikan salinan dalam objek, dan tidak perlu mengubah suai kelas
<?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,不随新对象改变,还是保持了原来的属性,可以看到,序列化和反序列化可以实现对象的深拷贝 ?>
Terdapat juga kaedah ketiga, yang sebenarnya serupa dengan kaedah kedua json_decode untuk dicapai tugasan
Pembelajaran yang disyorkan :《Tutorial Video PHP》
Atas ialah kandungan terperinci Apakah perbezaan antara salinan dalam dan salinan cetek dalam php. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!