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

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

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

$copy_of_object = clone $object;

Когда программист запрашивает создание копии объекта, PHP 5 определит, был ли для этого объекта объявлен метод __clone() или нет. Если нет, будет вызван метод __clone(), объявленный по умолчанию, который скопирует все свойства объекта. Если метод __clone() был объявлен, создание копий свойств в копии объекта полностью возлагается на него. Для удобства, движок обеспечивает программиста функцией, которая импортирует все свойства из объекта-источника, так что программист может осуществить позначное копирование свойств и переопределять только необходимые.

Пример 19-30. Клонирование объекта

<?php
class MyCloneable {
   static
$id = 0;

   function
MyCloneable() {
      
$this->id = self::$id++;
   }

   function
__clone() {
      
$this->address = "Москва";
      
$this->id = self::$id++;
   }
}

$obj = new MyCloneable();

$obj->name = "Привет";
$obj->address = "Самара";

print
$obj->id . "\n";

$obj_cloned = clone $obj;

print
$obj_cloned->id . "\n";
print
$obj_cloned->name . "\n";
print
$obj_cloned->address . "\n";
?>


Клонирование объектов
olle dot remove_this dot suni at rdnsoftware dot com
16-May-2006 04:49
As jorge dot villalobos at gmail dot com pointed out, the "__clone is NOT an override".

However, if one needs a true copy of an object (which has real copies of all subobjects too, not references), one can define a class method such as this to the object-to-be-cloned:

public function copy()
{
   $serialized_contents = serialize($this);
   return unserialize($serialized_contents);
}

The method makes a string representation of the object's contents (including subobjects), which can then be unserialized back to an object.

The method usage is simple:

$original_object = new MyCloneable(); //can have sub objects
$copied_object = $original_object->clone(); //only makes copies of the values, not references

With serialization, you surely don't have to worry about references, since serialized object is just simple text.
ove at junne dot dk
08-Feb-2006 08:02
Consider this:

function myfunc()
{
   $A = new myobject(); // Create another mysql connection
   $A->method1();        // Runs a query (works)
}

$A = new myobject(); // Create a mysql connection
myfunc();
$A->method1();  // This query fails! Possible because leaving the function has closed the connection.

Conclusion: Declaration of objects within and outside a function WITH THE SAME NAME, will affect each other. Do not relay on the rules of scope.

Take care when using recursive structures!!

It took me a long time to figure out.
markus dot amsler at oribi dot org
20-Jun-2005 06:14
For php4 you can use the clone method from the PEAR PHP_Compat package (http://pear.php.net/package/PHP_Compat).
jorge dot villalobos at gmail dot com
30-Mar-2005 03:29
I think it's relevant to note that __clone is NOT an override. As the example shows, the normal cloning process always occurs, and it's the responsibility of the __clone method to "mend" any "wrong" action performed by it.

<Ключевое слово "final"Сравнение объектов>
 Last updated: Tue, 15 Nov 2005