Клонирование объекта приводит к созданию новой копии объекта, при этом конструктор объекта не вызывается, в чём можно убедиться, поместив в конструктор вывод отладочной записи. Пример:


class MethodClone {

	public $_newElement;

	function __construct() {
		$this->_newElement = __CLASS__;
		echo 'Конструктор класса - '. $this->_newElement;
	}
}

$_Class_MethodClone = new MethodClone();
$_new_MethodClone = clone $_Class_MethodClone;

В результате работы скрипта в окно браузера будет выведена лишь одна запись "Конструктор класса - MethodClone". Тем не менее, в процессе создания нового объекта может потребоваться выполнить ряд действий. Для этого PHP предоставляет специальный метод "__clone()", который можно переопределить в классе.

При создании нового объекта в конструкторе статическая переменная "$_newElement" увеличивается на единицу. Однако, как было продемонстрировано выше, при клонировании конструктор не вызывается, и в системе появляются неучтённые объекты. Перегрузка метода "__clone()" позволяет исправить такую ситуацию.


class MethodClone {

	public static $_newElement = 0;
	public $work;

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

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

}

$ob = new MethodClone();

echo '<pre>';
print_r($ob);
echo '</pre>';

$ob2 = clone $ob;

echo '<pre>';
print_r($ob2);
echo '</pre>';

Результат:


MethodClone Object
(
[work] => 1
)
MethodClone Object
(
[work] => 2
)

Метод "__clone()" не вмешивается в работу процесса клонирования, то есть разработчик не должен реализовывать механизм клонирования самостоятельно, он может лишь использовать метод "__clone()" для реакции на процесс клонирования.

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

Приведём ещё пример, где в процессе клонирования единственному члену "$_newElement", присваивается значение "Клон", при этом изменения касаются лишь нового объекта.


class MethodClone {

	public $_newElement;

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

	public function __clone() {
		$this->_newElement = '<div>Клон</div>';
	}

}

$_Class_MethodClone = new MethodClone();
$_new_MethodClone = clone $_Class_MethodClone;

echo $_new_MethodClone->_newElement; # Результат: "Клон";
echo $_Class_MethodClone->_newElement; # Результат: "MethodClone";

Комментарии

captcha
 12 авг. 2015 Ответить

Спасибо за понятное объяснение! А то в официальных доках ничего не понял :)