Клонирование объектов

Создание копии объекта с абсолютно идентичными свойствами не всегда является приемлемым вариантом. Хорошим примером необходимости копирования конструкторов может послужить ситуация, когда у вас есть объект, представляющий собой окно GTK и содержащий ресурс-идентификатор этого окна; когда вы создаёте копию этого объекта, вам может понадобиться, чтобы копия объекта содержала ресурс-идентификатор нового окна. Другим примером может послужить ситуация, когда ваш объект содержит ссылку на какой-либо другой используемый объект и, когда вы создаёте копию родительского объекта, вам нужно также создать новый экземпляр этого другого объекта, так, чтобы копия объекта-контейнера содержала собственный отдельный экземпляр содержащегося объекта.

Копия объекта создаётся с использованием ключевого слова clone (который вызывает метод __clone() объекта, если это возможно).

$copy_of_object = clone $object;

При клонировании объекта, PHP выполняет поверхностную копию всех свойств объекта. Любые свойства, являющиеся ссылками на другие переменные, останутся ссылками.

__clone(): void

После завершения клонирования, если метод __clone() определён, то будет вызван метод __clone() вновь созданного объекта для возможного изменения всех необходимых свойств.

Пример #1 Клонирование объекта

<?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()
{
// Принудительно клонируем this->object1, иначе
// он будет указывать на один и тот же объект.
$this->object1 = clone $this->object1;
}
}

$obj = new MyCloneable();

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

$obj2 = clone $obj;


print
"Оригинальный объект:\n";
print_r($obj);

print
"Клонированный объект:\n";
print_r($obj2);

?>

Результат выполнения приведённого примера:

Оригинальный объект:
MyCloneable Object
(
    [object1] => SubObject Object
        (
            [instance] => 1
        )

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

)
Клонированный объект:
MyCloneable Object
(
    [object1] => SubObject Object
        (
            [instance] => 3
        )

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

)

Возможно обращаться к свойствам/методам только что склонированного объекта:

Пример #2 Доступ к только что склонированному объекту

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

Вывод приведённого примера будет похож на:

2016