Menu
Coddy logo textTech

__clone e Clonagem de Objetos

Parte da seção Programação Orientada a Objetos do Journey de PHP da Coddy. Lição 48 de 91.

Quando você atribui um objeto a outra variável em PHP, não cria uma cópia — ambas as variáveis apontam para o mesmo objeto. Para criar uma cópia independente de fato, você precisa usar a palavra-chave 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;

Saída:

999.99 - 899.99

Por padrão, o PHP realiza uma cópia superficial — ele copia diretamente todos os valores das propriedades. Isso funciona bem para valores escalares, mas os objetos dentro do seu objeto ainda fazem referência à mesma instância. O método mágico __clone() permite personalizar esse comportamento:

<?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;

Saída:

Original: 101, Clone: 0

O método __clone() é chamado no novo objeto após a criação da cópia superficial. É nesse ponto que você redefine os IDs, cria novas cópias de objetos aninhados ou realiza qualquer limpeza necessária para que o clone seja verdadeiramente independente.

challenge icon

Desafio

Fácil

Vamos criar um sistema de versionamento de documentos que demonstra como a clonagem cria cópias independentes e como o método mágico __clone() permite personalizar o que acontece quando um objeto é clonado.

Você organizará seu código em dois arquivos:

  • Document.php: crie uma classe Document que represente um documento versionado. Use a promoção de construtor para definir um $title público (string), um $content público (string) e um $version público (inteiro, com valor padrão 1). Adicione uma propriedade $createdAt privada que armazene o timestamp atual (use date('Y-m-d H:i:s') no construtor). Seu documento precisa de:
    • getCreatedAt(): retorna o timestamp de criação
    • __clone(): quando um documento é clonado, a versão deve ser incrementada em 1, e $createdAt deve ser redefinido para o timestamp atual (o clone é uma nova versão criada "agora")
  • main.php: inclua o arquivo Document. Você receberá três entradas: um título, um conteúdo e uma nova string de conteúdo para a versão clonada. Crie um Document com o título e o conteúdo. Em seguida, clone-o para criar uma nova versão e atualize o conteúdo do clone com a nova string de conteúdo. Imprima quatro linhas:
    • A versão do documento original
    • A versão do documento clonado
    • O conteúdo do documento original
    • O conteúdo do documento clonado

Este sistema mostra como __clone() permite controlar o que acontece durante a clonagem. O documento original mantém sua versão e seu horário de criação, enquanto o clone se torna automaticamente uma nova versão com um timestamp atualizado, perfeito para acompanhar o histórico do documento, em que cada clone representa uma nova revisão.

Experimente você mesmo

<?php

require_once 'Document.php';

// Ler entradas
$title = trim(fgets(STDIN));
$content = trim(fgets(STDIN));
$newContent = trim(fgets(STDIN));

// TODO: Crie um Document com o título e o conteúdo

// TODO: Clone o documento para criar uma nova versão

// TODO: Atualize o conteúdo do clone para a nova string de conteúdo

// TODO: Imprima quatro linhas:
// 1. A versão do documento original
// 2. A versão do documento clonado
// 3. O conteúdo do documento original
// 4. O conteúdo do documento clonado

?>
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de PHP online