Menu
Coddy logo textTech

__clone y clonación de objetos

Parte de la sección Programación Orientada a Objetos del Journey de PHP de Coddy. Lección 48 de 91.

Cuando asignas un objeto a otra variable en PHP, no creas una copia: ambas variables apuntan al mismo objeto. Para crear una copia independiente real, necesitas usar la palabra clave 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;

Salida:

999.99 - 899.99

De forma predeterminada, PHP realiza una copia superficial: copia directamente todos los valores de las propiedades. Esto funciona bien para los valores escalares, pero los objetos dentro de tu objeto siguen haciendo referencia a la misma instancia. El método mágico __clone() te permite personalizar este comportamiento:

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

Salida:

Original: 101, Clone: 0

El método __clone() se llama en el nuevo objeto después de realizar la copia superficial. Aquí es donde restableces los ID, creas copias nuevas de los objetos anidados o realizas cualquier limpieza necesaria para que el clon sea verdaderamente independiente.

challenge icon

Desafío

Fácil

Construyamos un sistema de versionado de documentos que demuestre cómo la clonación crea copias independientes y cómo el método mágico __clone() permite personalizar lo que ocurre cuando se clona un objeto.

Organizarás tu código en dos archivos:

  • Document.php: Crea una clase Document que represente un documento versionado. Usa la promoción de constructor para definir un $title público (string), un $content público (string) y un $version público (integer, con un valor predeterminado de 1). Añade una propiedad privada $createdAt que almacene la marca de tiempo actual (usa date('Y-m-d H:i:s') en el constructor). Tu documento necesita:
    • getCreatedAt(): devuelve la marca de tiempo de creación
    • __clone(): cuando se clona un documento, la versión debe incrementarse en 1 y $createdAt debe restablecerse a la marca de tiempo actual (el clon es una nueva versión creada "ahora")
  • main.php: Incluye el archivo Document. Recibirás tres entradas: un título, un contenido y una nueva cadena de contenido para la versión clonada. Crea un Document con el título y el contenido. Después clónalo para crear una nueva versión y actualiza el contenido del clon con la nueva cadena de contenido. Imprime cuatro líneas:
    • La versión del documento original
    • La versión del documento clonado
    • El contenido del documento original
    • El contenido del documento clonado

Este sistema muestra cómo __clone() permite controlar lo que ocurre durante la clonación. El documento original conserva su versión y su hora de creación, mientras que el clon se convierte automáticamente en una nueva versión con una marca de tiempo actualizada, perfecto para realizar un seguimiento del historial de documentos en el que cada clon representa una nueva revisión.

Pruébalo tú mismo

<?php

require_once 'Document.php';

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

// TODO: Crea un Document con el título y el contenido

// TODO: Clona el documento para crear una nueva versión

// TODO: Actualiza el contenido del clon a la nueva cadena de contenido

// TODO: Imprime cuatro líneas:
// 1. La versión del documento original
// 2. La versión del documento clonado
// 3. El contenido del documento original
// 4. El contenido del documento clonado

?>
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de PHP online