zoukankan      html  css  js  c++  java
  • php 克隆 clone

    php 克隆 clone

    在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也就是说,A与B是两个独立的对象,但B的初始值是由A对象确定的。

    在php语言中,用简单的赋值语句是不能满足这种需求的。要满足这种需求虽然有很多途径,但实现clone()方法是其中最简单,也是最高效的手段。

    在php5中,对象的传递方式默认为引用传递。

    $copy_of_object = clone $object;//$object和$copy_of_object是不同的对象,不过$copy_of_object的值是在$object基础加$object事例对象里clone()方法改变后的实例

    当对象被复制后,PHP5会对对象的所有属性执行一个“浅复制”(shallow copy)。所有的属性中的引用 仍然不变,指向原来的变量。如果定义了__clone()方法,则新创建的对象(复制生成的对象)中的__clone()方法会被调用, 可用于修改属性的值(如果有必要的话)。

    核心:

    $obj = new MyCloneable();

     $obj2 = clone $obj;

    //调用MyCloneable::__clone方法。clone方法重置想改变项,返回修改后的类的实例给pbj2.

    <?php
    class SubObject
    {

        public $name;
        public $age;
        public function __construct() {
            echo '~~~~__construct OB~~~~<br>';
            $this->name = 'dayi';
            $this->age = 7;
        }

        public function __clone() {
           
            echo '~~~~333~~~~<br>';
            $this->name = 'xiaobai';
            $this->age = 8;
        }
    }

    class MyCloneable
    {
        public $object1;
        public $object2;

        public function __construct() {
            echo '~~~~__construct OA~~~~<br>';

        }
        function __clone()
        {
          echo '~~~~2222~~~~<br>';
            //print_r($this->object1); SubObject Object ( [name] => [age] => 7 )
            $this->object1 = clone $this->object1;     //调用SubObject::__clone方法。clone方法重置想改变项(变为xiaobai,8),返回修改后的类的实例给$this->object1.
            // print_r($this->object1);SubObject Object ( [name] => xiaobai [age] => 8 )
            echo '&&&&444&&&&<br>';
            }
    }

    $obj = new MyCloneable();
    echo '!!!1111!!!<br>';
    $obj->object1 = new SubObject();

    $obj->object2 = new SubObject();

    $obj2 = clone $obj;//调用MyCloneable::__clone方法。clone方法重置想改变项,返回修改后的类的实例给pbj2.

    echo '@@@555@@@<br><br><br>';

    print("原对象: ");
    var_dump($obj);

    echo '<br><br><br>';
    print("Cloned 对象: ");
    var_dump($obj2);

    ###################结果###################

    ~~~~__construct OA~~~~
    !!!1111!!!
    ~~~~__construct OB~~~~
    ~~~~__construct OB~~~~
    ~~~~2222~~~~
    ~~~~333~~~~
    &&&&444&&&&
    @@@555@@@


    原对象: object(MyCloneable)#1 (2) { ["object1"]=> object(SubObject)#2 (2) { ["name"]=> string(4) "dayi" ["age"]=> int(7) } ["object2"]=> object(SubObject)#3 (2) { ["name"]=> string(4) "dayi" ["age"]=> int(7) } }


    Cloned 对象: object(MyCloneable)#4 (2) { ["object1"]=> object(SubObject)#5 (2) { ["name"]=> string(7) "xiaobai" ["age"]=> int(8) } ["object2"]=> object(SubObject)#3 (2) { ["name"]=> string(4) "dayi" ["age"]=> int(7) } }


    核心:所有的属性中的引用 仍然不变,指向原来的变量。

    class ByRef
    {
        var $prop;
        function __construct()
         {
            $this->prop =& $this->prop;
             $this->prop1 = 'haha, i am here';
        }
         function __clone()
        {   
                $this->prop=2;// $a->prop is now 2
        }
    }
    $a = new ByRef;
    $a->prop = 1;
    echo '原对象: ';var_dump($a);echo '<br><br>';

    $b = clone $a;//本句替换成 $b=$a,结果也还是3,不过不会触发ByRef::__clone, prop不会中间变成2。本例研究的是克隆后,$b->prop引用不变
    echo '原对象: ';var_dump($a);echo '<br>';
    echo 'clone 对象: ';var_dump($b);echo '<br><br>';
    $b->prop = 3; // $a->prop is now 3
    $b->prop1 = 'oh,u move'; // b的prop1 改变了,a的prop1没变
    echo '原对象: ';var_dump($a);echo '<br>';
    echo 'clone 对象: ';var_dump($b);echo '<br><br>';
    echo '原对象的引用prop: ';echo $a->prop;echo '<br>';
    echo 'clone 对象的引用prop: ';echo $b->prop;

    ###################结果###################

    原对象: object(ByRef)#6 (2) { ["prop"]=> &int(1) ["prop1"]=> string(15) "haha, i am here" }

    原对象: object(ByRef)#6 (2) { ["prop"]=> &int(2) ["prop1"]=> string(15) "haha, i am here" }
    clone 对象: object(ByRef)#7 (2) { ["prop"]=> &int(2) ["prop1"]=> string(15) "haha, i am here" }

    原对象: object(ByRef)#6 (2) { ["prop"]=> &int(3) ["prop1"]=> string(15) "haha, i am here" }
    clone 对象: object(ByRef)#7 (2) { ["prop"]=> &int(3) ["prop1"]=> string(9) "oh,u move" }

    原对象的引用prop: 3
    clone 对象的引用prop: 3

  • 相关阅读:
    如何手动同步 Chrome 浏览器的数据
    如何释放 Windows 10 系统的 C 盘空间
    Foxmail
    常用 Git 命令
    常用的 .gitignore 模板
    MySQL InnoDB Engine--数据页存储和INSERT操作
    MySQL InnoDB Engine--数据页存储和ALTER TABLE操作
    MySQL InnoDB Engine--数据页存储
    MySQL Index--BAK和MRR演示
    MySQL Execute Plan--Index Merge特性
  • 原文地址:https://www.cnblogs.com/lansetiankongblog/p/7833454.html
Copyright © 2011-2022 走看看