Objeto Clone PHP

Resumo : neste tutorial, você aprenderá como clonar um objeto usando a palavra-chave clone em PHP.

Clonar um objeto é criar uma cópia de um objeto. A clonepalavra-chave permite realizar uma cópia superficial de um objeto. Ao combinar a clonepalavra-chave e __clone()o método mágico, você pode realizar uma cópia profunda de um objeto.

Será mais fácil entender os conceitos de clone, cópia superficial e cópia profunda por meio de exemplos.

Configurando

O exemplo a seguir define uma Personclasse simples que possui uma propriedade $name. Para simplificar, tornaremos a $namepropriedade pública:

<?php

class Person
{
	public $name;

	public function __construct($name)
	{
		$this->name = $name;
	}
}Linguagem de código:  HTML, XML  ( xml )

Copiando objeto via atribuição

O seguinte ilustra como copiar um objeto por meio do operador de atribuição :

<?php

class Person
{
	public $name;

	public function __construct($name)
	{
		$this->name = $name;
	}
}

$bob = new Person('Bob');
// assign bob to alex and change the name
$alex = $bob;


$alex->name = 'Alex';

// show both objects
var_dump($bob);
var_dump($alex);Linguagem de código:  HTML, XML  ( xml )

Saída:

object(Person)#1 (1) {
  ["name"]=> string(4) "Alex"
}
object(Person)#1 (1) {
  ["name"]=> string(4) "Alex"
}Linguagem de código:  PHP  ( php )

O var_dump() mostra um objeto com o #1.

Como funciona.

  • Primeiro, crie uma nova instância da Personclasse chamada $bobcom as $namepropriedades definidas como 'Bob'.
  • Segundo, atribua $bobe $alexaltere o valor da $namepropriedade para 'Alex'.
  • Terceiro, use a var_dump()função para mostrar os dois objetos.

Neste exemplo, ambos $bobe $alexfazem referência ao mesmo objeto na memória. Quando alteramos a propriedade de um objeto, isso se reflete em ambas as referências.

Copiando objeto usando a palavra-chave clone

PHP fornece a clonepalavra-chave que permite criar uma cópia superficial de um objeto. Por exemplo:

$bob = new Person('Bob');

// clone an object
$alex = clone $bob;
$alex->name = 'Alex';

// show both objects
var_dump($bob);
var_dump($alex);Linguagem de código:  PHP  ( php )

Saída:

object(Person)#1 (1) {
  ["name"]=> string(3) "Bob"
}
object(Person)#2 (1) {
  ["name"]=> string(4) "Alex"
}Linguagem de código:  PHP  ( php )

Neste exemplo, a clonepalavra-chave cria uma cópia do Personobjeto. Existem dois objetos na memória. Portanto, alterar a propriedade de um objeto não afeta o outro:

Também var_dump()mostra os objetos #1 e #2.

Método mágico PHP __clone

O __clone()é um método mágico com a seguinte sintaxe:

function __clone ( ) : voidLinguagem de código:  JavaScript  ( javascript )

Se você definir o clone()método, o PHP irá executá-lo automaticamente quando a clonagem for concluída. Isso clone()é útil quando você deseja alterar as propriedades do objeto copiado.

Cópia superficial

Conforme mencionado anteriormente, o cloneexecuta uma cópia superficial de um objeto. Significa que:

  • Crie uma cópia de todas as propriedades de um objeto.
  • Se uma propriedade fizer referência a outro objeto, a propriedade permanecerá uma referência.

Em outras palavras, quando um objeto possui uma propriedade que faz referência a outro objeto, essa propriedade permanece uma referência após a clonagem.

Vejamos o seguinte exemplo:

<?php

class Address
{
	public $street;

	public $city;
}

class Person
{
	public $name;

	public $address;

	public function __construct($name)
	{
		$this->name = $name;
		$this->address = new Address();
	}
}Linguagem de código:  HTML, XML  ( xml )

Neste exemplo:

  • Primeiro, defina uma nova classe chamada Addressque tenha duas propriedades $citye $street.
  • Segundo, altere a Personclasse adicionando a addresspropriedade. No construtor, inicialize o addresspara um novo Addressobjeto.

A Personclasse tem a addresspropriedade como referência.

O seguinte cria um novo Personobjeto chamado $bobe atribui as propriedades da addresspropriedade:

$bob = new Person('Bob');
$bob->address->street = 'North 1st Street';
$bob->address->city = 'San Jose';

var_dump($bob);Linguagem de código:  PHP  ( php )

Saída:

object(Person)#1 (2) {
  ["name"]=>  string(3) "Bob"
  ["address"]=> object(Address)#2 (2) {        
    ["street"]=> string(16) "North 1st Street"
    ["city"]=> string(8) "San Jose"
  }
}Linguagem de código:  PHP  ( php )

O var_dump()mostra dois objetos Person(#1) e Address(#2). O Personobjeto possui a addresspropriedade que faz referência ao Addressobjeto.

O seguinte cria uma cópia do $bobobjeto e a atribui a $alex. Também altera o valor da $namepropriedade para 'Alex':

$alex = clone $bob;
$alex->name = 'Alex';

var_dump($alex);Linguagem de código:  PHP  ( php )

Saída:

object(Person)#3 (2) {
  ["name"]=> string(4) "Alex"
  ["address"]=> object(Address)#2 (2) {
    ["street"]=> string(16) "North 1st Street"
    ["city"]=> string(8) "San Jose"
  }
}Linguagem de código:  PHP  ( php )

Mostra var_dump()o novo Personobjeto (#3) que é uma cópia do objeto Person (#1). No entanto, a addresspropriedade do novo Personobjeto ainda faz referência ao mesmo Addressobjeto:

Isso significa que ambos Personos objetos possuem a addresspropriedade que faz referência ao mesmo Addressobjeto. Alterar o Addressobjeto de $alexafetará $bob:

$alex->address->street = '1 Apple Park Way';
$alex->address->city = 'Cupertino';

var_dump($bob);Linguagem de código:  PHP  ( php )

Saída:

object(Person)#1 (2) {
  ["name"]=> string(3) "Bob" 
  ["address"]=> object(Address)#2 (2) {
    ["street"]=> string(16) "1 Apple Park Way"
    ["city"]=> string(9) "Cupertino"
  }
}Linguagem de código:  PHP  ( php )

Junte tudo:

<?php

class Address
{
	public $street;

	public $city;
}

class Person
{
	public $name;

	public $address;

	public function __construct($name)
	{
		$this->name = $name;
		$this->address = new Address();
	}
}

$bob = new Person('Bob');
$bob->address->street = 'North 1st Street';
$bob->address->city = 'San Jose';

var_dump($bob);

$alex = clone $bob;
$alex->name = 'Alex';

var_dump($alex);

$alex->address->street = '1 Apple Park Way';
$alex->address->city = 'Cupertino';

var_dump($bob);Linguagem de código:  HTML, XML  ( xml )

Cópia profunda com método __clone

A cópia profunda cria uma cópia de um objeto e cria recursivamente uma cópia dos objetos referenciados pelas propriedades do objeto.

Como o PHP chama o __clone()método automaticamente após clonar um objeto, você pode clonar os objetos referenciados pelas propriedades da classe.

O exemplo a seguir ilustra como usar o __clone()método mágico para transportar uma cópia profunda do Personobjeto:

<?php

class Address
{
	public $street;

	public $city;
}

class Person
{
	public $name;

	public $address;

	public function __construct($name)
	{
		$this->name = $name;
		$this->address = new Address();
	}

	public function __clone()
	{
		$this->address = clone $this->address;
	}
}

$bob = new Person('Bob');
$bob->address->street = 'North 1st Street';
$bob->address->city = 'San Jose';

$alex = clone $bob;
$alex->name = 'Alex';
$alex->address->street = '1 Apple Park Way';
$alex->address->city = 'Cupertino';

var_dump($bob);
var_dump($alex);
Linguagem de código:  HTML, XML  ( xml )

Saída:

object(Person)#1 (2) {
  ["name"]=> string(3) "Bob"
  ["address"]=> object(Address)#2 (2) {
    ["street"]=> string(16) "North 1st Street"
    ["city"]=> string(8) "San Jose"
  }
}

object(Person)#3 (2) {
  ["name"]=> string(4) "Alex"
  ["address"]=> object(Address)#4 (2) {
    ["street"]=> string(16) "1 Apple Park Way"
    ["city"]=> string(9) "Cupertino"
  }
}Linguagem de código:  PHP  ( php )

A novidade aqui é __clone()o método na classe Person. O __clone()método cria uma cópia do Addressobjeto.

Cópia profunda usando funções serializar e desserializar

Outra maneira de transportar uma cópia profunda de um objeto é usar as funções serialize()e unserialize().

A serialize()função cria uma representação armazenável de um objeto enquanto a função unserialize() cria um objeto a partir do valor armazenável.

A deep_clone()função a seguir cria uma cópia profunda de um objeto:

<?php

function deep_clone($object)
{
	return unserialize(serialize($object));
}Linguagem de código:  HTML, XML  ( xml )

Resumo

  • Use clonepara realizar uma cópia superficial de um objeto.
  • Combine clonee __clone()método para criar uma cópia profunda de um objeto.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *