PHP에서 객체 참조, 얕은 복사본, 깊은 복사본을 이해하는 방법

不言
풀어 주다: 2023-03-23 12:36:01
원래의
1433명이 탐색했습니다.

이 글은 PHP의 객체 참조, 얕은 복사, 깊은 복사를 이해하는 방법을 공유합니다. 도움이 필요한 친구들이 참고할 수 있습니다.

많은 초보 PHP 사용자는 oop 프로그래밍에 익숙하지 않아 이러한 개념을 무시하는 경향이 있습니다. "주니어 PHP 엔지니어"라는 책을 읽으면서 객체 참조 부분에 대해 상당히 모호했습니다. 몇 가지 정보를 확인하고 이해했습니다. 여기에 기록을 남기고 이러한 기반을 통합해야 한다고 스스로에게 말하고 싶었습니다.

참고기사: https://blog.csdn.net/hel12he/article/details/49617023

                                                           ~       https://blog.csdn.net/koastal/article/details/52163483

우선 먼저 해야 할 일은 PHP 메모리 공간이 어떻게 분배되는지 이해합니다. 일반적으로 메모리 공간은 아래와 같이 힙 메모리, 스택 메모리, 데이터 세그먼트, 코드 세그먼트로 구분됩니다.

그럼 객체 참조란 무엇일까요?

new 키워드를 사용하여 클래스를 인스턴스화하면 이 개체를 통해 클래스의 속성과 메서드에 액세스할 수 있습니다. 그리고 각 객체는 독립적입니다. 예를 들어 자동차 클래스는 크기, 색상, 운전 방법과 같은 속성을 가지며, 이 클래스는 여러 객체로 인스턴스화될 수 있으며, 각 객체의 속성 메서드를 수정할 수 있습니다. 인스턴스 클래스의 속성과 메소드를 포함하는 자체 메모리 공간이 있습니다. 객체에 대한 참조 또는 별칭을 사용하면 실제로 동일한 메모리 공간을 가리킵니다. 예:

<?php
  class One
{
    public $name;

    public function __construct($name)
    {
        $this->name = $name;
    }
}
//实例化,并且向构造函数传递参数
$o1 = new One(&#39;test1&#39;);
echo "对象1的name值为:".$o1->name."<br/>";
//引用
$o2 = $o1;
//打印对象2的$name属性
echo "对象2的name值为:".$o2->name."<br/>";
//修改对象$o2的$name属性
echo "修改对象2的name为test2"."<br/>";
$o2->name = &#39;test2&#39;;
//比较此时两个对象的$name值
echo "修改后对象1的name值为:".$o1->name."<br/>";
echo "修改后对象2的name值为:".$o2->name."<br/>";
로그인 후 복사

인쇄 결과:

그것은 가능합니다. 참조는 본질적으로 객체의 별칭일 뿐이라는 것을 알 수 있습니다. 실제로 참조된 객체와 참조하는 객체가 가리키는 메모리 공간은 여전히 ​​동일합니다. (여기서 $o2=&o1 의 효과는 동일합니다).


그래서 얕은 복사란 무엇일까요?

개념: 복제본을 사용하여 개체를 복사합니다. 이러한 종류의 복사본을 "얕은 복사본"이라고 합니다. 할당된 개체의 모든 변수는 여전히 원본 개체와 동일한 값을 가지며 다른 개체에 대한 모든 참조는 여전히 원본을 가리킵니다. 물체. . 즉, 얕은 복사본은 참조하는 개체가 아닌 고려 중인 개체만 복사합니다.

동일한 예를 사용하여 $o2=$o1을 $o2=clone $o1로 변경해 보겠습니다. 인쇄 결과는 아래와 같습니다.


객체 2의 값만 수정했을 때 객체 1은 변경되지 않았음을 알 수 있습니다. 왜냐하면 clone 키워드를 사용하면 객체의 복사본이 생성되기 때문입니다. 이 복사본에도 자체 메모리 공간이 있으며 이전에는 서로 독립적이었습니다. 그러나 얕은 복사에서는 참조하는 개체가 복사되지 않습니다.


前面说的东西都是内容只有数值的情况,当内容中也有引用的对象那就不一样了,也就引出了深复制的概念。

深复制概念:被复制的对象的所有的变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。也就是说深复制把要复制的对象所引用的对象都复制了一遍。

两种方法:

利用__clone魔术方法

public function __clone()
{
    $this->obj = new Obj();
}
로그인 후 복사


利用串行化

$t = serialize($o1);
$o2 = unserialize($t);
로그인 후 복사


举个栗子:

<?php
header("Content-type:text/html;charset=utf-8");
class TvControl{
}
class Tv{
    private $color;
    private $tvControl;
    function __construct(){
        $this->color = "black";
        $this->tvControl = new TvControl();
    }
    
    function getTvControl(){
        return $this->tvControl;
    }
}
		$tv1 = new Tv();
		$tvControl1 = $tv1->getTvControl();
		echo "原始类:"."<br/>";
		var_dump($tv1);
		echo "<br/>";
		$tv2 = $tv1;
		echo "引用类:"."<br/>";
		var_dump($tv2);
		echo "<br/>";
		$tv3 = clone $tv1;
		echo "克隆(浅复制):"."<br/>";
		var_dump($tv3);
		echo "<br/>";
		$tv4 = unserialize(serialize($tv1));
		echo "深复制:"."<br/>";
		var_dump($tv4);
로그인 후 복사

打印结果:


深复制获取到的对象也是一个全新的对象。

那么如何比较两个对象是否引用于同一个对象呢?

"==="를 사용하여 두 객체가 동일한 초기 객체를 참조하는지 비교할 수 있습니다. 그리고 "=="는 두 객체가 동일한 클래스와 속성을 가지고 있는지 여부만 비교할 수 있습니다.

관련 권장 사항:

PHP 배열의 카운트 기능에 대한 심층적인 이해

PHP 루프 문에 대한 심층적인 이해


위 내용은 PHP에서 객체 참조, 얕은 복사본, 깊은 복사본을 이해하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!