Home  >  Article  >  Backend Development  >  Detailed explanation of php__clone() cloning method and usage examples of shallow cloning and deep cloning

Detailed explanation of php__clone() cloning method and usage examples of shallow cloning and deep cloning

伊谢尔伦
伊谢尔伦Original
2017-07-17 11:57:452954browse

You can define a clone() method in the object class to adjust the object's cloning behavior. The code for this method will be executed during the cloning operation. In addition to copying all existing object members to the target object, the operations specified by the clone() method are performed. Next, modify the Corporate_Drone class and add the following methods:

function clone() { 
 $this->tiecolor = "blue";
}

After that, create a new Corporate_Drone object, increase the value of the employeeid member, clone the object, and then output some data to show that the tiecolor of the cloned object is indeed It is set through the clone() method. Sample code:

<?php
 // Create new corporatedrone object
  $drone1 = new corporatedrone();
 
 // Set the $drone1 employeeid member
  $drone1->setEmployeeID("12345");
 
 // Clone the $drone1 object
  $drone2 = clone $drone1;
 
 // Set the $drone2 employeeid member
  $drone2->setEmployeeID("67890");
 
 // Output the $drone1 and $drone2 employeeid members
  echo "drone1 employeeID: ".$drone1->getEmployeeID()."<br />";
  echo "drone2 employeeID: ".$drone2->getEmployeeID()."<br />";
  echo "drone2 tiecolor: ".$drone2->getTiecolor()."<br />";
?>

Program running result

drone1 employeeID: 12345
drone2 employeeID: 67890
drone2 tiecolor:

Another small example:

<?php
class Fruit {
 private $name = "水果";
 private $color = "颜色";
 
 public function setName($name){
 $this->name = $name;
 }
 
 public function setColor($color){
 $this->color = $color;
 }
 
 function showColor(){
 return $this->color.&#39;的&#39;.$this->name."<br />";
 }
 
 function destruct(){
 echo "被吃掉了(对象被回收) <br />"; 
 }
}

$apple = new Fruit();
$apple->setName("大苹果");
$apple->setColor("红色");
echo $apple->showColor();

$clone_apple = $apple;
$clone_apple->setName("小苹果");
$clone_apple->setColor("青色");

echo $clone_apple->showColor();
?>

The above just assigns one class to another class, so at this time the memory is still an object.

<?php
class Fruit {
 private $name = "水果";
 private $color = "颜色";
 
 public function setName($name){
 $this->name = $name;
 }
 
 public function setColor($color){
 $this->color = $color;
 }
 
 function showColor(){
 return $this->color.&#39;的&#39;.$this->name."<br />";
 }
 
 function destruct(){
 echo "被吃掉了(对象被回收) <br />"; 
 }
 function clone(){
 $this->name = "克隆水果"; 
 }
}

$apple = new Fruit();
$apple->setName("大苹果");
$apple->setColor("红色");
echo $apple->showColor();

$clone_apple = clone $apple;
$clone_apple->setColor("青色");

echo $clone_apple->showColor();
?>

The clone method clones a new class, so there are two objects in the memory at this time.

php's clone() method makes a shallow copy of an object instance. The basic numeric type in the object is copied by value, and the object-type member variables in the object, if If you do not override the clone method and explicitly clone the object member variable, the member variable will be copied by reference instead of generating a new object. As shown in the comment on line 28 of the following example What is said

<?php
  class Account {
    public $balance;
    
    public function construct($balance) {
      $this->balance = $balance;
    }
  }
 
  class Person {
    private $id;
    private $name;
    private $age;
    public $account;
    
    public function construct($name, $age, Account $account) {
      $this->name = $name;
      $this->age = $age;
      $this->account = $account;
    }
    
    public function setId($id) {
      $this->id = $id;
    }
    
    public function clone() {  #复制方法,可在里面定义再clone是进行的操作
      $this->id = 0;
      $this->account = clone $this->account;  #不加这一句,account在clone是会只被复制引用,其中一个account的balance被修改另一个也同样会被修改
    }
  }
  
  $person = new Person("peter", 15, new Account(1000));
  $person->setId(1);
  $person2 = clone $person;
  
  $person2->account->balance = 250;
  
  var_dump($person, $person2);
  
 ?>

Shallow cloning: It only clones the non-object non-resource data in the object, that is, the attributes in the object store the object type, then incomplete cloning will occur

<?php
class B{
 public $val = 10;
}
class A{
 public $val = 20;
 public $b;
 public function construct(){
  $this->b = new B();
 }
}
$obj_a = new A();
$obj_b = clone $obj_a;
$obj_a->val = 30;
$obj_a->b->val = 40;
var_dump($obj_a);
echo &#39;<br>&#39;;
var_dump($obj_b);

Run The results are as follows:

object(A)[1]
 public &#39;val&#39; => int 30
 public &#39;b&#39; =>
 object(B)[2]
  public &#39;val&#39; => int 40
 
object(A)[3]
 public &#39;val&#39; => int 20
 public &#39;b&#39; =>
 object(B)[2]
  public &#39;val&#39; => int 40

Deep cloning: All attribute data of an object are completely copied. You need to use the magic methodclone() and implement deep cloning inside it

<?php
class B{
 public $val = 10;
}
class A{
 public $val = 20;
 public $b;
 public function construct(){
  $this->b = new B();
 }
 public function clone(){
  $this->b = clone $this->b;
 }
}
$obj_a = new A();
$obj_b = clone $obj_a;
$obj_a->val = 30;
$obj_a->b->val = 40;
var_dump($obj_a);
echo &#39;<br>&#39;;
var_dump($obj_b);

The running results are as follows:

object(A)[1]
 public &#39;val&#39; => int 30
 public &#39;b&#39; =>
 object(B)[2]
  public &#39;val&#39; => int 40
 
object(A)[3]
 public &#39;val&#39; => int 20
 public &#39;b&#39; =>
 object(B)[4]
  public &#39;val&#39; => int 10

The above is the detailed content of Detailed explanation of php__clone() cloning method and usage examples of shallow cloning and deep cloning. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn