Clonando objetos

Criar uma cópia de um objeto com propriedades totalmente replicadas nem sempre é o comportamento desejado. Um bom exemplo da necessidade para construtores de cópia é se você tem um objeto que representa uma janela do GTK e um objeto guarda o resource dessa janela. Quando você criar uma duplicata, você pode querer criar uma nova janela com as mesmas propriedades e fazer o novo objeto quarda o resource da nova janela. Outro exemplo é se seu objeto guarda uma referência a outro objeto o qual ele usa e quando você replicar o objeto pai, você quer 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). O método __clone() de um objeto não pode ser chamado diretamente.

$copia_do_objeto = clone $objeto;

Quando um objeto é clonado, PHP 5 fará uma cópia superficial de todas as propriedades do objeto. Qualquer propriedade que seja referência a outra variável, permanecerá referência. Se um método __clone() for definido, então este será chamado, permitindo definir qualquer alteração necessária nas propriedades.

Exemplo 19-29. Clonando um objeto

<?php
class SubObjeto {
  static
$instancias = 0;
  
public $instancia;

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

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

class
MeuClonavel {

  
public $objeto1;
  
public $objeto2;

  function
__clone() {
    
// Força uma cópia de this->objeto, ou então
    // apontará para o mesmo objeto
    
$this->objeto1 = clone($this->objeto1);
  }
}

$obj = new MeuClonavel();

$obj->objeto1 = new SubObjeto();
$obj->objeto2 = new SubObjeto();

$obj2 = clone $obj;


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

print(
"Objeto Clonado:\n");
print_r($obj2);

?>

O exemplo acima irá imprimir:

Objeto Original:
MeuClonavel Object
(
    [objeto1] => SubObjeto Object
        (
            [instancia] => 1
        )

    [objeto2] => SubObjeto Object
        (
            [instancia] => 2
        )

)
Objeto Clonado:
MeuClonavel Object
(
    [objeto1] => SubObjeto Object
        (
            [instancia] => 3
        )

    [objeto2] => SubObjeto Object
        (
            [instancia] => 2
        )

)