Forum und email

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.

Example#1 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
        )

)