PHP Cookbook: Solutions and Examples for PHP Programmers
7.10.1. Problem
You want to copy an object. 7.10.2. Solution
Copy objects by reference using =: $rasmus = $zeev; Copy objects by value using clone: $rasmus = clone $zeev;
7.10.3. Discussion
PHP 5 copies objects by reference instead of value. When you assign an existing object to a new variable, that new variable is just another name for the existing object. Accessing the object by the old or new name produces the same results. To create an independent instance of a value with the same contents, otherwise known as copying by value, use the clone keyword. Otherwise, the second object is simply a reference to the first. This cloning process copies every property in the first object to the second. This includes properties holding objects, so the cloned object may end up sharing object references with the original. This is frequently not the desired behavior. For example, consider the aggregated version of Person that holds an Address object in Example 7-26. Using an aggregated class
An aggregated class is one that embeds another class inside in a way that makes it easy to access both the original and embedded classes. The key point to remember is that the $address property holds an Address object. With this class, Example 7-27 shows what happens when you clone an object. Cloning an aggregated class
Interesting. Calling setName( ) worked correctly because the $name property is a string, so it's copied by value. However, since $address is an object, it's copied by reference, so getCity( ) doesn't produce the correct results, and you end up relocating Rasmus to Tel Aviv. This type of object cloning is known as a shallow clone or a shallow copy. In contrast, a "deep clone" occurs when all objects involved are cloned. This is PHP 4's cloning method. Control how PHP 5 clones an object by implementing a __clone( ) method in your class. When this method exists, PHP allows __clone( ) to override its default behavior, as shown in Example 7-28. Properly implementing cloning in aggregated classes
Inside of __clone( ), you're automatically presented with a shallow copy of the variable, stored in $this, the object that PHP provides when __clone( ) does not exist. Since PHP has already copied all the properties, you only need to overwrite the ones you dislike. Here, $name is okay, but $address needs to be explicitly cloned. Now the clone behaves correctly, as shown in Example 7-29. Cloning an aggregated class
Using the clone operator on objects stored in properties causes PHP to check whether any of those objects contain a __clone( ) method. If one exists, PHP calls it. This repeats for any objects that are nested even further. This process correctly clones the entire object and demonstrates why it's called a deep copy. 7.10.4. See Also
Recipe 7.9 for more on assigning objects by reference. |
Категории