Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Apakah perbezaan antara salinan dalam dan salinan cetek dalam php

Apakah perbezaan antara salinan dalam dan salinan cetek dalam php

WBOY
WBOYasal
2022-02-10 09:53:472714semak imbas

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.

Apakah perbezaan antara salinan dalam dan salinan cetek dalam php

Persekitaran pengendalian tutorial ini: sistem Windows 10, versi PHP 7.1, komputer DELL G3

Perbezaan antara salinan dalam dan salinan cetek dalam php ialah Apa

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!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn