객체 복제 심층 분석
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에서 복제해야 합니다.
챌린지
쉬움얕은 복제와 deep cloning의 차이를 보여 주는 문서 관리 시스템을 만들어 보겠습니다. author 정보를 포함하는 document를 만들고, document를 복제하면 완전히 독립적인 복사본이 생성되도록 합니다.
코드를 세 개의 파일로 구성합니다.
Author.php: document의 author를 나타내는Authorclass를 Create합니다. constructor promotion을 사용하여 public$name(string)과 public$email(string)을 define합니다.Document.php: author를 포함하는Documentclass를 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합니다.
- public
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: 복제된 문서의 정보 출력
?>이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 PHP 컴파일러