Оглавление

Клонирование

В версии PHP 4 представление объектов не осуществлялось по ссылке. То есть, при передаче объекта в вызов метода или функции создавалась копия этого объекта. Мало того, что это было связано с трудностями, такой вариант мог порождать серьезные проблемы с отслеживанием ошибок. Поскольку создавалась копия объекта, любые изменения в экземпляре этого объекта, произведенные в методе или функции, влияли только на копию объекта в функции. В версии PHP 5 такое нелогичное поведение было устранено; теперь все объекты представляются по ссылке. Несмотря на серьезность изменения, прямые копии экземпляра объекта больше не создаются:


$class_one = new MyClass();
$class_one_copy = $class_one;

Анализируя этот пример, можно было бы предположить, что $class_one_copy на самом деле является независимым экземпляром класса MyClass, имеющим все особенности экземпляра $class_one. Так было в PHP 4, а в PHP 5 $class_one и $class_one_copy представляют один и тот же объект — любые модификации, произведённые в одном из экземпляров, приведут к такому же изменению в другом. В PHP 5 вместо прямого присваивания экземпляру объекта новой переменной необходимо использовать оператор clone. Он возвращает новый экземпляр текущего объекта, копируя в него значения любого члена и, таким образом, создавая независимый клон.

В связи с этим, в PHP 5 код, приведенный в листинге 8, можно было бы использовать для создания независимой копии объекта, на основе которого был создан экземпляр.


$class_one = new MyClass();
$class_one_copy = clone $class_one;

При использовании оператора clone по умолчанию возвращается точная копия клонированного объекта. Однако класс также может реализовать специальный метод __clone(), позволяющий управлять элементами, которые будут копироваться из одного экземпляра в другой. В этом специальном методе переменная $this ссылается на новую копию объекта вместе со всеми значениями из исходного объекта. Код в листинге 9 показывает, что с помощью метода __clone() можно управлять значениями клонированного объекта.

 


class myObject {
    public $var_one = 10;
    public $var_two = 20;
    function __clone() {
        /* переменной $var_two в клоне присваивается значение 0 */
        $this->var_two = 0;
    }
}

$inst_one = new myObject();
$inst_two = clone $inst_one;
var_dump($inst_one);
var_dump($inst_two);

 

В данном примере вывод будет выглядеть следующим образом:


object(myObject)#1 (2) {
  ["var_one"]=>
  int(10)
  ["var_two"]=>
  int(20)
}
object(myObject)#2 (2) {
  ["var_one"]=>
  int(10)
  ["var_two"]=>
  int(0)
}

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

Комментарии принадлежат их авторам. Мы не несем ответственности за их содержание.
Отправитель Нити