[PHP] Copy (copy) and _ clone () Methods of objects, php _ clone
Reference link:
1. php.net official website documentation-object Replication
When will it be used? From php.net:
In most cases, we do not need to completely copy an object to obtain its attributes. However, you need to: If you have a GTK window object, the object holds window-related resources. You may want to copy a new window to keep all attributes the same as the original window, but it must be a new object (because if it is not a new object, changes in one window will affect the other window ). Another case is: If object A contains the reference of object B, when you copy object A, you want to use the object instead of object B but A copy of object B, then you must get A copy of object.
Try to use the simplest "="
First of all, it should be clear that php objects are stored as an identifier. Therefore, the direct "value assignment" of objects is equivalent to "passing reference"
<?phpfunction dump($var){ var_dump($var); echo "<br/>";}class A{ private $a; protected $b; public $c; public function d(){ echo "A -> d"; }}$a1 = new A();$a2 = $a1;$a3 = new A();dump($a1);dump($a2);dump($a3);
The output result is:
object(A)#1 (3) { ["a":"A":private]=> NULL ["b":protected]=> NULL ["c"]=> NULL } object(A)#1 (3) { ["a":"A":private]=> NULL ["b":protected]=> NULL ["c"]=> NULL } object(A)#2 (3) { ["a":"A":private]=> NULL ["b":protected]=> NULL ["c"]=> NULL }
It can be noted that # n of the object identifier shows that $ a1 and $ a2 actually point to the same object, while $ a3 is another object.
Therefore, if you want to copy an identical and brand-new object, you cannot copy it directly through =. Otherwise, if you change $ a1-> a, it is equivalent to modifying $ a2->.
Shortest copy
In PHP5, there is a magic method _ clone () in the class. It is automatically called when used with the clone keyword and object (if it is not explicitly defined, call the empty method ).
The clone keyword is used to copy an object to form a "shortest copy" of the object, and then assign the value to the new object. At this time, the object identifier is different!
<? Phpfunction dump ($ var) {var_dump ($ var); echo "<br/>" ;}class B {public $ d ;}class A {public $; public $ B; public function d () {echo "A-> d" ;}}$ a1 = new A (); $ a1-> a = 123; // here, the object property value is an object example, which actually stores the object identifier. The B attribute in the copy generated by using the clone keyword still points to the object pointed to by the B attribute of the old object, which is a problem in "shortest copy. To point to a new object, you must "Deep copy" $ a1-> B = new B (); // PHP 5 only $ a2 = clone $ a1; dump ($ a1); dump ($ a2 );
The output result is:
object(A)#1 (2) { ["a"]=> int(123) ["b"]=> object(B)#2 (1) { ["d"]=> NULL } } object(A)#3 (2) { ["a"]=> int(123) ["b"]=> object(B)#2 (1) { ["d"]=> NULL } }
As you can see, $ a1 and $ a2 are obviously two different objects (object identifiers are different ). However, note that the object identifiers pointed to by "B" are both #2, proving that the two objects are the same, this is the "defect" of "Shallow copy"-but sometimes these two objects must be the same, so PHP's clone is "Shallow copy" by default ".
Why is shallow copy )?
During replication, all attributes are "passed values", and the above B attributes store object identifiers, so it is equivalent to "passed references ", this is not a complete copy, so it is called "shortest copy ".
Deep copy
As mentioned above, when the clone keyword is used, the _ clone () method of the old object is automatically called (and then the Copied object is returned ), therefore, you only need to rewrite the _ clone () method in the corresponding class to direct the "reference transfer" attribute in the returned object to another new object. The following is an example (we can compare the example of "shortest copy". In fact, the rewrite _ clone () step is added ):
<? Phpfunction dump ($ var) {var_dump ($ var); echo "<br/>" ;}class B {public $ d ;}class A {public $; public $ B; public function d () {echo "A-> d";} public function _ clone () {// clone yourself $ this-> B = clone $ this-> B ;}}$ a1 = new A (); $ a1-> a = 123; // here, the object property value is an object example, which actually stores the object identifier. The B attribute in the copy generated by using the clone keyword still points to the object pointed to by the B attribute of the old object, which is a problem in "shortest copy. To point to a new object, you must "Deep copy" $ a1-> B = new B (); // PHP 5 only $ a2 = clone $ a1; dump ($ a1); dump ($ a2 );
The results are different. Note the object identifier of the B attribute:
object(A)#1 (2) { ["a"]=> int(123) ["b"]=> object(B)#2 (1) { ["d"]=> NULL } } object(A)#3 (2) { ["a"]=> int(123) ["b"]=> object(B)#4 (1) { ["d"]=> NULL } }