>백엔드 개발 >PHP 문제 >PHP에서 깊은 복사와 얕은 복사의 차이점은 무엇입니까?

PHP에서 깊은 복사와 얕은 복사의 차이점은 무엇입니까?

WBOY
WBOY원래의
2022-02-10 09:53:472815검색

PHP에서 깊은 복사와 얕은 복사의 차이점: 1. 깊은 복사는 값을 할당할 때 완전한 복사본인 반면 얕은 복사는 별칭을 사용하는 것과 동일한 참조 할당일 뿐입니다. 2. 깊은 복사가 값을 변경하는 경우; 그 중 하나는 다른 하나에 영향을 미치지 않으며 하나에 대한 얕은 복사 수정은 다른 하나에도 영향을 미칩니다.

PHP에서 깊은 복사와 얕은 복사의 차이점은 무엇입니까?

본 튜토리얼의 운영 환경: Windows 10 시스템, PHP 버전 7.1, DELL G3 컴퓨터

PHP에서 전체 복사와 얕은 복사의 차이점은 무엇인가요? 복사: 할당하면 값이 완전히 복사됩니다. 전체 복사본 중 하나를 변경해도 다른 복사본에는 영향이 없습니다. 할당 시 참조 할당은 별칭을 사용하는 것과 같습니다. 둘 중 하나를 수정하면 다른 하나에도 영향을 미칩니다.

PHP에서 =가 할당되면 일반 개체는 깊은 복사본이지만 개체의 경우 얕은 복사본입니다. 즉, 객체 할당은 참조 할당입니다. (객체가 매개변수로 전달되면 함수 정의 시 매개변수 앞에 앰퍼샌드가 있는지 여부에 관계없이 참조로도 전달됩니다.)

php4에서 객체의 = 할당은 복사, 많은 문제가 있습니다. 우리는 무의식적으로 많은 복사본을 만들 수 있습니다.

PHP5에서는 객체의 할당과 전송이 모두 참조입니다. 복사본을 구현하기 위해 PHP는 복제 기능 구현을 제공합니다.

Clone은 완전한 복사본을 만듭니다. 그러나 복제할 때 소스 객체의 모든 내용을 복사하고 싶지 않을 경우 __clone을 사용하여 작업할 수 있습니다.

__clone()에서는 몇 가지 작업을 수행할 수 있습니다. 이러한 작업, 즉 __clone 함수는 복사된 복사본 개체에 대해 작동합니다

<?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;
?>

할당 중에 개체가 참조되므로 값 복사를 달성하기 위해 PHP는 개체를 복사하는 복제 함수를 제공합니다.

그런데 복제 기능에 문제가 있습니다. 객체를 복제하면 원본 객체의 일반 속성을 값으로 복사할 수 있지만 원본 객체의 객체 속성을 할당하면 여전히 참조 할당이고 얕습니다. 사본.

<?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,随新对象改变
?>

 객체의 진정한 전체 복사본을 얻으려면 두 가지 방법이 있습니다:

clone 함수 작성: 다음과 같이

<?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,不随新对象改变,还是保持了原来的属性
 
?>

 __clone() 함수를 다시 작성하는 것은 편리하지 않으며 이 클래스를 각 클래스의 객체 속성은 모두 __clone()

에서 하나씩 복제됩니다. 두 번째 방법은 직렬화 및 역직렬화로 구현됩니다. 이 방법은 객체의 전체 복사본을 구현하는 것이 간단하며 클래스를 수정할 필요가 없습니다

<?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,不随新对象改变,还是保持了原来的属性,可以看到,序列化和反序列化可以实现对象的深拷贝
 
?>

세 번째 방법도 있습니다. 이 방법은 실제로 두 번째 방법과 유사합니다. json_encode 이후에는 json_decode를 사용하여 할당을 구현합니다. 권장 학습: "

PHP Video Tutorial

"

위 내용은 PHP에서 깊은 복사와 얕은 복사의 차이점은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.