Menu
Coddy logo textTech

__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이 진정으로 독립적이 되기 위해 필요한 정리를 수행합니다.

challenge icon

챌린지

쉬움

cloning이 독립적인 복사본을 생성하는 방식과 __clone() magic method를 통해 객체가 clone될 때 발생하는 일을 사용자 지정하는 방법을 보여 주는 document versioning 시스템을 만들어 보겠습니다.

코드를 두 파일에 걸쳐 구성합니다:

  • Document.php: version이 지정된 document를 나타내는 Document class를 Create합니다. constructor promotion을 사용하여 public $title(string), public $content(string), public $version(정수, default는 1)을 정의합니다. current timestamp를 저장하는 private $createdAt property를 추가합니다( 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. 복제된 문서의 내용

?>
quiz icon실력 점검

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

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

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