너의 개발은/PHP

PHP: 객체 비교와 복사

객체 비교

객체에 대한 비교단순히 가지고 있는 값이 똑같은지 비교하는 것과 객체의 주소값이 같은지를 비교하는 것이 있습니다. 각각 ==, === 연산자를 사용하고, 아래의 코드를 보면, 두 개의 객체는 서로 다른 주소값을 가지고 있기 때문에 === 를 사용했을 때 false 를 반환합니다. 아주 단순하지만 이는 중요합니다.

$class1 = new stdClass();
$class2 = new stdClass();

var_dump($class1 == $class2); // -> true
var_dump($class1 === $class2); // -> false

객체 복사

결론부터 이야기하자면 PHP는 clone 키워드를 통해 복사하는 경우 기본적으로 얕은 복사입니다. 복사는 단순 복사, 얕은 복사, 깊은 복사가 존재하는데 저마다 다릅니다. 또한 참조까지 잠깐 이야기해보도록 하겠습니다.

단순 복사

단순 복사는 객체의 주소값만 복사합니다. 따라서 어느 한 쪽의 상태가 변경되면 다른 한 쪽의 상태도 변경됩니다. 

// $class3 = $class1 = <Object Id>
$class3 = $class1;

$class1->message = 'Hello, world';
var_dump($class3->message); // -> Hello, world

참조

참조는 단순 복사와 비슷하게 움직이지만, 내부적으로 다릅니다. 주소값을 복사한다기 보다는 그냥 같은 공간을 공유하고 있는 것이죠.

// ($myclass3, $myclass1) = <Object Id>
$class3 =& $class1;

$class1->message = 'Hello, world';
var_dump($class3->message); // -> Hello, world

얕은 복사

얕은 복사는 외부 객체는 깊은 복사처럼 객체를 새로 만들지만, 만약 객체 내부에 또 다른 객체가 있다면 그 객체는 주소값만 복사됩니다. clone 키워드를 통해 사용합니다.

$class3 = clone $class1;
var_dump($class1 === $class3); // -> false

$array1 = new ArrayObject([ 1, 2, new ArrayObject([ 3, 4 ]) ]);
$array2 = clone $array1;

var_dump($array1[2] === $array2[2]); // -> true

깊은 복사

깊은 복사는 객체 내부에 있는 객체까지 새로 만듭니다. 이것은 별도로 구현해야 합니다. 매직 메서드 __clone()clone 키워드로 복사를 할 때 호출되는데, 여기서 깊은 복사를 처리해줄 수 있습니다. 예를 들면 다음과 같이 말이죠!

class MyArrayObject implements ArrayAccess, IteratorAggregate
{
    public function __clone()
    {
        array_walk($this->container, fn (&$value) => is_object($value) ? $value = clone $value : null);
    }
    
    // ...
}

$array1 = new MyArrayObject([ 1, 2, new MyArrayObject([ 3, 4 ]) ]);
$array2 = clone $array1;

var_dump($array1 === $array2); // -> false
var_dump($array1[2] === $array2[2]); // -> false

내부에 있는 객체를 돌면서 요소가 객체라면 clone 을 사용하여 복사처리를 해주는 것을 볼 수 있습니다.

Serialize

직렬화를 사용해도 깊은 복사를 할 수 있습니다. 매직 메서드를 사용할 필요도 없이 그저 serialize(), unserialize() 를 사용하면 됩니다.

$array2 =  unserialize(serialize($array1));

var_dump($array1 === $array2); // -> false
var_dump($array1[2] === $array2[2]); // -> false

 

 

PHP 7+ 프로그래밍: 리부트 - 인프런

기초 문법부터 내장 함수, 웹 보안, 게시판 만들기까지 PHP 언어를 시작하는 분들을 위해 바이블이 될 수 있게 만들어보고자 하는 마음으로 이번 강좌를 만들어보았습니다. 입문 웹 개발 프로그��

www.inflearn.com

 

PHP 7+ 프로그래밍: 객체지향 - 인프런

PHP 객체지향, 내장 클래스, PSR, Composer, MVC(Model, View, Controller)까지 모던 PHP를 익히기 위한 근간을 이야기합니다. 초급 프로그래밍 언어 알고리즘 PHP 객체지향 알고리즘 온라인 강의 모던 PHP 프로��

www.inflearn.com

'너의 개발은 > PHP' 카테고리의 다른 글

PHP: 쿠키와 세션  (0) 2020.04.29
PHP: HTML 폼 (GET, POST)  (0) 2020.04.29
PHP: 객체 비교와 복사  (0) 2020.04.25
PHP: 참조 (WeakReference)  (0) 2020.04.25
PHP: 제네레이터 (Iterator)  (0) 2020.04.24
PHP: 에러와 예외 (try, catch, finally)  (1) 2020.04.23