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 clone
palavra-chave permite realizar uma cópia superficial de um objeto. Ao combinar a clone
palavra-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 Person
classe simples que possui uma propriedade $name
. Para simplificar, tornaremos a $name
propriedade 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
Person
classe chamada$bob
com as$name
propriedades definidas como'Bob'
. - Segundo, atribua
$bob
e$alex
altere o valor da$name
propriedade para'Alex'
. - Terceiro, use a
var_dump()
função para mostrar os dois objetos.
Neste exemplo, ambos $bob
e $alex
fazem 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 clone
palavra-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 clone
palavra-chave cria uma cópia do Person
objeto. 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 ( ) : void
Linguagem 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 clone
executa 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
Address
que tenha duas propriedades$city
e$street
. - Segundo, altere a
Person
classe adicionando aaddress
propriedade. No construtor, inicialize oaddress
para um novoAddress
objeto.
A Person
classe tem a address
propriedade como referência.
O seguinte cria um novo Person
objeto chamado $bob
e atribui as propriedades da address
propriedade:
$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 Person
objeto possui a address
propriedade que faz referência ao Address
objeto.
O seguinte cria uma cópia do $bob
objeto e a atribui a $alex
. Também altera o valor da $name
propriedade 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 Person
objeto (#3) que é uma cópia do objeto Person (#1). No entanto, a address
propriedade do novo Person
objeto ainda faz referência ao mesmo Address
objeto:
Isso significa que ambos Person
os objetos possuem a address
propriedade que faz referência ao mesmo Address
objeto. Alterar o Address
objeto de $alex
afetará $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 Person
objeto:
<?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 Address
objeto.
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
clone
para realizar uma cópia superficial de um objeto. - Combine
clone
e__clone()
método para criar uma cópia profunda de um objeto.