zoukankan      html  css  js  c++  java
  • php引用复制,浅复制clone和深复制

    1.引用复制

    <?php 
    class  a {
        public $info=0;
    }
    $a=new a();
    $b=$a;  //引用赋值
    $a->info="10";
    echo $a->info."<br>";
    echo $b->info."<br>";
    die; 

    结果如下:

     

    2.浅复制clone

    <?php 
    class  a {
        public $info=0;
    }
    $a=new a();
    $b=clone $a;  //clone
    $a->info="10";
    echo $a->info."<br>";
    echo $b->info."<br>";
    die;
    

      结果如下

     

    那么为什么叫浅复制呢,因为它只能复制类里面的属性和方法,如果类里面的属性和方法用到的其他的对象,那么复制过去的也是引用复制,如下:

    <?php 
    class mybianliang {
        public $bianliagn=0;
        public function __construct($bianliang){
            $this->bianliang=$bianliang;
        }
        public function changebianliang($bianliang2){
            $this->bianliang=$bianliang2;
        }
    }
    class  mytest {
        public $test=0;
        public function __construct($bianliang){
            $this->test=new mybianliang($bianliang);
        }
    }
    $a=new mytest(10);
    $b= clone $a;   //clone
    echo $a->test->bianliang."<br>";  
    $a->test->changebianliang(20);       //改变a对象中test对象中的属性值,看看b对象中的test对象中的属性可有变化
    echo $b->test->bianliang."<br>";
    die;
    

      结果如下:

     这说明 $b对象中的$test对象指向的是$a对象的$test对象,那么如何避免呢

    用__clone魔术方法把类中用的其他对象重新clone一下

    <?php 
    class mybianliang {
        public $bianliagn=0;
        public function __construct($bianliang){
            $this->bianliang=$bianliang;
        }
        public function changebianliang($bianliang2){
            $this->bianliang=$bianliang2;
        }
    }
    class  mytest {
        public $test=0;
        public function __construct($bianliang){
            $this->test=new mybianliang($bianliang);
        }    
        public function __clone(){
            $this->test=clone $this->test;   //克隆一下这个对象,不然指向的还是同一个对象
        } 
    }
    $a=new mytest(10);
    $b= clone $a;   //clone
    echo $a->test->bianliang."<br>";  
    $a->test->changebianliang(20);       //改变a对象中test对象中的属性值,看看b对象中的test对象可有变化
    echo $b->test->bianliang."<br>";
    die;

    结果如下

     3.深复制

       深复制,可以利用上面的魔术方法__clone()或者利用序列化和反序列化的方法

    <?php 
    class mybianliang {
        public $bianliagn=0;
        public function __construct($bianliang){
            $this->bianliang=$bianliang;
        }
        public function changebianliang($bianliang2){
            $this->bianliang=$bianliang2;
        }
    }
    class  mytest {
        public $test=0;
        public function __construct($bianliang){
            $this->test=new mybianliang($bianliang);
        }
    
    }
    
    $a=new mytest(10);
    $b = unserialize(serialize($a));   //序列化和反序列化
    echo $a->test->bianliang."<br>";  
    $a->test->changebianliang(20);       //改变a对象中test对象中的属性值,看看b对象中的test对象可有变化
    echo $b->test->bianliang."<br>";
    die;
    

      执行结果

  • 相关阅读:
    Springboot开发微信公众号(四)
    Springboot开发微信公众号(三)
    springboot中Scheduled不执行的原因
    static方法里用@Autowire或者@Resource注入的属性
    Spring boot 读取配置文件application.yml (自定义属性值)
    Apache-Flink深度解析-SQL概览
    Apache-Flink深度解析-DataStream-Connectors之Kafka
    Apache-Flink深度解析-JOIN 算子
    Apache-Flink深度解析-TableAPI
    Spark streaming消费Kafka的正确姿势
  • 原文地址:https://www.cnblogs.com/flyyu/p/14119974.html
Copyright © 2011-2022 走看看