Clonando objetos

Criar uma cópia de um objeto com propriedades totalmente replicadas nem sempre é o comportamento desejado. Um bom exemplo da necessidade para cópia de construtores, e quando possuir um objeto que representa uma janela do GTK e o objeto guarda o recurso dessa janela GTK. ao criar uma duplicata, pode-se desejar a criação de uma nova janela com as mesmas propriedades e fazer o novo objeto guardar o recurso da nova janela. Outro exemplo é se seu objeto guarda uma referência a outro objeto que usa e ao replicar o objeto pai, deseja-se que seja criada uma nova instância desse outro objeto para que a réplica tenha sua própria cópia separada.

Uma cópia de objeto é criada usando a palavra-chave clone (que chama o método __clone() do objeto, se possível).

$copia_do_objeto = clone $objeto;

Ao se clonar um objeto, o PHP fará uma cópia superficial de todas as propriedades do objeto. Qualquer propriedade que seja referência a outra variável, permanecerá como referência.

__clone(): void

Depois que a clonagem se completa, se um método __clone() estiver definido, o objeto recém criado terá seu método __clone() chamado, permitindo que qualquer propriedade seja alterada.

Example #1 Clonando um objeto

<?php
class SubObject
{
    static $instances = 0;
    public $instance;

    public function __construct() {
        $this->instance = ++self::$instances;
    }

    public function __clone() {
        $this->instance = ++self::$instances;
    }
}

class MyCloneable
{
    public $object1;
    public $object2;

    function __clone()
    {
        // Force a copy of this->object, otherwise
        // it will point to same object.
        $this->object1 = clone $this->object1;
    }
}

$obj = new MyCloneable();

$obj->object1 = new SubObject();
$obj->object2 = new SubObject();

$obj2 = clone $obj;


print "Original Object:\n";
print_r($obj);

print "Cloned Object:\n";
print_r($obj2);

?>

O exemplo acima produzirá:

Original Object:
MyCloneable Object
(
    [object1] => SubObject Object
        (
            [instance] => 1
        )

    [object2] => SubObject Object
        (
            [instance] => 2
        )

)
Cloned Object:
MyCloneable Object
(
    [object1] => SubObject Object
        (
            [instance] => 3
        )

    [object2] => SubObject Object
        (
            [instance] => 2
        )

)

É possível acessar um membro de um objeto recém clonado em uma expressão única:

Example #2 Acessar um membro de um objeto recém clonado

<?php
$dateTime = new DateTime();
echo (clone $dateTime)->format('Y');
?>

O exemplo acima produzirá algo semelhante a:

2016