__clone 및 객체 복제
Coddy PHP 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 91개 중 48번째.
PHP에서 한 객체를 다른 변수에 할당하면 복사본이 생성되지 않습니다. 두 변수 모두 동일한 객체를 가리킵니다. 실제로 독립적인 copy를 만들려면 clone 키워드를 사용해야 합니다:
<?php
class Product {
public function __construct(
public string $name,
public float $price
) {}
}
$original = new Product("Laptop", 999.99);
$copy = clone $original;
$copy->price = 899.99;
echo $original->price . " - " . $copy->price;
출력:
999.99 - 899.99기본적으로 PHP는 얕은 복사를 수행합니다. 즉, 모든 속성 값을 직접 복사합니다. 이는 스칼라 값에는 잘 작동하지만, 객체 내부의 객체는 여전히 동일한 인스턴스를 참조합니다. __clone() 매직 메서드를 사용하면 이 동작을 사용자 지정할 수 있습니다.
<?php
class Order {
public function __construct(
public int $id,
public array $items = []
) {}
public function __clone(): void {
$this->id = 0;
$this->items = [];
}
}
$order1 = new Order(101, ["Book", "Pen"]);
$order2 = clone $order1;
echo "Original: " . $order1->id . ", Clone: " . $order2->id;
출력:
Original: 101, Clone: 0얕은 복사가 완료된 후 새 객체에서 __clone() method가 호출됩니다. 여기서 ID를 재설정하고, 중첩된 객체의 새로운 copy를 생성하거나, clone이 진정으로 독립적이 되기 위해 필요한 정리를 수행합니다.
챌린지
쉬움cloning이 독립적인 복사본을 생성하는 방식과 __clone() magic method를 통해 객체가 clone될 때 발생하는 일을 사용자 지정하는 방법을 보여 주는 document versioning 시스템을 만들어 보겠습니다.
코드를 두 파일에 걸쳐 구성합니다:
Document.php: version이 지정된 document를 나타내는Documentclass를 Create합니다. constructor promotion을 사용하여 public$title(string), public$content(string), public$version(정수, default는 1)을 정의합니다. current timestamp를 저장하는 private$createdAtproperty를 추가합니다( constructor에서date('Y-m-d H:i:s')를 사용). document에는 다음이 필요합니다:getCreatedAt(): creation timestamp를 반환합니다__clone(): document가 clone되면 version이 1만큼 증가하고,$createdAt이 current timestamp로 Reset되어야 합니다(clone은 "now"에 createdAt된 새 version입니다)
main.php: Document 파일을 Include합니다. 세 가지 inputs를 받습니다: title, content, 그리고 cloned version을 위한 새 content string입니다. title과 content로Document를 Create합니다. 그런 다음 이를 clone하여 새 version을 만들고, clone의 content를 새 content string으로 Update합니다. 네 줄을 Print합니다:- original document의 version
- cloned document의 version
- original document의 content
- cloned document의 content
이 시스템은 __clone()을 사용하여 cloning 중 발생하는 일을 제어하는 방법을 보여 줍니다. original document는 자신의 version과 creation time을 유지하는 반면, clone은 자동으로 새로운 version과 새 timestamp를 갖게 되므로, 각 clone이 새로운 revision을 나타내는 document history를 추적하는 데 적합합니다.
직접 해보기
<?php
require_once 'Document.php';
// 입력 읽기
$title = trim(fgets(STDIN));
$content = trim(fgets(STDIN));
$newContent = trim(fgets(STDIN));
// TODO: 제목과 내용으로 Document 생성
// TODO: 문서를 복제하여 새 버전 생성
// TODO: 복제본의 내용을 새 내용 문자열로 업데이트
// TODO: 네 줄 출력:
// 1. 원본 문서의 버전
// 2. 복제된 문서의 버전
// 3. 원본 문서의 내용
// 4. 복제된 문서의 내용
?>이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 PHP 컴파일러