Клонирование объекта приводит к созданию новой копии объекта, при этом конструктор объекта не вызывается, в чём можно убедиться, поместив в конструктор вывод отладочной записи. Пример:
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";
Спасибо за понятное объяснение! А то в официальных доках ничего не понял :)