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("原对象:\n");
var_dump($obj);

echo '<br><br><br>';
print("Cloned 对象:\n");
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

php 克隆 clone的更多相关文章

  1. 数组复制的五种方式(遍历循环一一赋值、System.arraycopy、地址赋值、克隆clone()、Arrays.copyof())

    package com.Summer_0424.cn; import java.util.Arrays; import java.util.concurrent.CopyOnWriteArrayLis ...

  2. Java中的克隆(CLONE)

    解读克隆 编程过程中我们常常遇到如下情况: 假设有一个对象object,在某处又需要一个跟object一样的实例object2,强调的是object和object2是两个独立的实例,只是在 开始的时候 ...

  3. GitHub下载克隆clone指定的分支tag代码

    需求描述: 这边有很多tag分支版本的代码,我想克隆下载指定版本到我服务器上面 例如:我想下载tag:1.4.1的代码 解决方法: 命令:git clone --branch [tags标签] [gi ...

  4. java 浅拷贝和深拷贝 对象克隆clone

    分一下几点讨论: 为什么要克隆? 如何实现克隆 浅克隆和深克隆 解决多层克隆问题 总结 一:为什么要克隆? 大家先思考一个问题,为什么需要克隆对象?直接new一个对象不行吗? 答案是:克隆的对象可能包 ...

  5. DBA_实践指南系列3_Oracle Erp R12系统克隆Clone(案例)

    2013-12-03 Created By BaoXinjian

  6. 09_EGIT插件的安装,Eclipse中克隆(clone),commit,push,pull操作演示

     1 下载EGIT,下载地址:http://www.eclipse.org/egit/download/ 最终的下载地址: http://www.eclipse.org/downloads/dow ...

  7. Java 深度克隆 clone()方法重写 equals()方法的重写

    1.为什么要重写clone()方法? 答案:Java中的浅度复制是不会把要复制的那个对象的引用对象重新开辟一个新的引用空间,当我们需要深度复制的时候,这个时候我们就要重写clone()方法. 2.为什 ...

  8. 对象克隆(clone)实例详解

    <?php class Staff { public $name; public $age; public $salary; public function __construct($name, ...

  9. JAVA 构造器, extends[继承], implements[实现], Interface[接口], reflect[反射], clone[克隆], final, static, abstrac

    记录一下: 构造器[构造函数]: 在java中如果用户编写类的时候没有提供构造函数,那么编译器会自动提供一个默认构造函数.它会把所有的实例字段设置为默认值:所有的数字变量初始化为0;所有的布尔变量设置 ...

随机推荐

  1. linux配置词典goldendict

    在mint 18下使用通过, ubuntu 类似. 方法: 通过软件中心安装goldendict,或者 sudo apt install goldendict 通过网页抓取程序, 见附录 下载朗道词典 ...

  2. 显著水平|区间估计|假设检验|显著性|第一类错误|Ⅱ类错误|β错误|t检验|连续性矫正|二项分布的假设检验|样本百分率|

    第三章 假设检验 区间估计与假设检验的基本区别? 上一章中讨论了置信区间的估计方法.它是利用样本数据,以抽样总体的分布为理论基础,用一定的概率保证来计算出原总体中未知参数的区间范围.特别值得注意的是: ...

  3. 一个理解基本RCNN的简单例子

    对于一个最简单的RNN网络https://github.com/Teaonly/beginlearning/ """Minimal character-level Van ...

  4. python深度学习6.2

    Deep Learning with Python>第六章 6.2 理解循环神经网络(RNN) 神机喵算 2018.09.01 20:40 字数 2879 阅读 104评论 0喜欢 1 沉下心来 ...

  5. Java进行http请求时,放置会话信息到header里面

    public class CreateHttpTest { public static void main(String[] args) { createHttp(); } public static ...

  6. JKFZ%你赛炸裂祭

    Md爆40了身败名裂 上来就刚T1是什么习惯?居然不看T2导致明明能刚出正解却止步40 , T3找到原题看懂题解后却不敢交+难码 , 最近怕不是做毒瘤%你赛多了总以为T1能刚到点分 md最近怕不是炸了 ...

  7. 透过F5获取服务器真实内网IP

    渗透测试过程中,经常会遇到目标服务器使用F5 LTM做负载均衡. 如果能获取到目标服务器的真实IP地址,会给后续渗透带来一定便利. 本文既是最近渗透遇到的一点点经验分享. F5修改cookie机制 F ...

  8. Java多线程处理任务(摘抄)

    很多时候,我们需要对一个庞大的队列或者二维数组进行处理.这些处理可能是循环的,比如给一个excel多个sheet的联系人列表发邮件.很幼稚的方法就是用一个或者两个FOR循环搞定,对于庞大的数据有得让你 ...

  9. java中的赋值

    java中的赋值使用符号“=”. 按照java编程思想的解释:它的意思是“取等号右边的值,把它复制给左边”. 当然左边必须是一个明确的,已命名的变量. 基本类型: int a=2; int b=3; ...

  10. django-crontab使用

    用 django-crontab 为 Django 添加定时任务 需求 做后台开发的时候,有时候会遇到这样的需求,在某个固定时间或者一定时间间隔自动触发某一事件.比如说我有一个需求要求是,周一到周五早 ...