Menu
Coddy logo textTech

객체 복제 심층 분석

Coddy PHP 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 91개 중 61번째.

이 과정의 앞부분에서 __clone 매직 메서드에 대해 배웠습니다. 이제 객체가 다른 객체를 속성으로 포함할 때 얕은 복제와 deep 복제의 중요한 차이를 살펴보겠습니다.

기본적으로 PHP는 클론을 생성할 때 얕은 복사를 수행합니다. 스칼라 값은 복제되지만 객체 속성은 동일한 객체에 대한 참조로 남습니다.

<?php
class Address {
    public function __construct(public string $city) {}
}

class Person {
    public function __construct(
        public string $name,
        public Address $address
    ) {}
}

$original = new Person("Alice", new Address("Paris"));
$clone = clone $original;

$clone->name = "Bob";
$clone->address->city = "London";

echo $original->name . " - " . $original->address->city;

출력:

Alice - London

$clone->name을 변경해도 original에는 영향을 주지 않았지만, address city를 변경하자 영향을 주었습니다! 두 객체는 동일한 Address 인스턴스를 공유합니다.

중첩된 객체도 복제되는 깊은 복사를 만들려면 __clone을 구현하세요:

<?php
class Person {
    public function __construct(
        public string $name,
        public Address $address
    ) {}
    
    public function __clone(): void {
        $this->address = clone $this->address;
    }
}

$original = new Person("Alice", new Address("Paris"));
$clone = clone $original;
$clone->address->city = "London";

echo $original->address->city;

출력:

Paris

이제 각 Person은 고유한 독립 Address를 갖습니다. 객체에 중첩된 객체가 여러 개 포함되어 있는 경우, 원본과 복사본 사이에서 진정한 독립성을 확보하려면 각 객체를 __clone에서 복제해야 합니다.

challenge icon

챌린지

쉬움

얕은 복제와 deep cloning의 차이를 보여 주는 문서 관리 시스템을 만들어 보겠습니다. author 정보를 포함하는 document를 만들고, document를 복제하면 완전히 독립적인 복사본이 생성되도록 합니다.

코드를 세 개의 파일로 구성합니다.

  • Author.php: document의 author를 나타내는 Author class를 Create합니다. constructor promotion을 사용하여 public $name (string)과 public $email (string)을 define합니다.
  • Document.php: author를 포함하는 Document class를 Create합니다. Author 파일을 포함합니다. class는 다음을 수행해야 합니다.
    • public $title (string)과 public $author (Author)에 constructor promotion을 사용합니다.
    • __clone() magic method를 Implement하여 deep cloning을 수행합니다. document가 복제되면 author도 복제되어야 하므로, 복제본의 author를 변경해도 original에 영향을 주지 않아야 합니다.
    • getInfo() method를 가지며, "[title] by [author name] ([author email])"을 return합니다.
  • main.php: Document 파일을 포함합니다. 세 가지 inputs를 받습니다. document title, author name, author email입니다.

    provided inputs를 사용하여 Author와 함께 Document를 Create합니다. document를 복제한 다음, 복제본의 author name에 " (Copy)"를 appending하고 복제본의 title 앞에 "Copy of "를 prepending하여 변경합니다.

    두 줄을 Print합니다.

    • original document의 info
    • cloned document의 info

    deep cloning이 올바르게 Implement되었다면, 복제본의 author를 Modify한 후에도 original document의 author는 변경되지 않은 상태로 should remain 합니다.

이 challenge는 deep cloning이 중요한 이유를 보여 줍니다. __clone()을 제대로 Implement하지 않으면 두 document가 동일한 Author object를 공유하게 되어, 하나를 변경하면 다른 하나에도 영향을 주게 됩니다.

직접 해보기

<?php

require_once 'Document.php';

// 입력 읽기
$title = trim(fgets(STDIN));
$authorName = trim(fgets(STDIN));
$authorEmail = trim(fgets(STDIN));

// TODO: 제공된 이름과 이메일로 Author 생성

// TODO: 제공된 제목과 Author로 Document 생성

// TODO: 문서 복제

// TODO: 복제본의 작성자 이름에 " (Copy)"를 추가하여 수정

// TODO: 복제본의 제목 앞에 "Copy of "를 붙여 수정

// TODO: 원본 문서의 정보 출력

// TODO: 복제된 문서의 정보 출력

?>
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 PHP 컴파일러