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. LIINQ TO JS

    记录一下,方便自己查找... 自己在开发前端时,对于处理JSON,觉得真是枯燥.处理数据,基本都要循环. 所以我想着前端也能跟后端一样,有Linq来处理我的JSON对象就好了.上网一搜,找到了JSLI ...

  2. 黑马_13 Spring Boot:01.spring boot 介绍&&02.spring boot 入门

    13 Spring Boot: 01.spring boot 介绍&&02.spring boot 入门 04.spring boot 配置文件 SpringBoot基础 1.1 原有 ...

  3. LeetCode No.163,164,165

    No.163 FindMissingRanges 缺失的区间 题目 给定一个排序的整数数组 nums ,其中元素的范围在闭区间 [lower, upper] 当中,返回不包含在数组中的缺失区间. 示例 ...

  4. numpy(二)

    1.集合操作 包含去重,交,并,差集操作 2.排序.搜索和计数 sort,where,argmin,argmax,count_nonzero,argwhere 3.线性代数 np.linalg库,包含 ...

  5. Java常用的公共方法

    --获取规字符串中的指定名称的某个字段值 1.public String getValueByName(String params,String name) --用于通过表单选中的复选框获取它的值(j ...

  6. tensorflow用法记录

    使用 embedding 变量 import tensorflow as tf import numpy as np sess = tf.InteractiveSession() M = list(' ...

  7. IdentityServer4之Token令牌获取流程分析

    1.asp.net core 是基于管道模式IdentityServer会在注册一个管道处理程序 IdentityServerMiddleware 类专门处理登录验证的逻辑,本次主要讲的是access ...

  8. 发布订阅--SQLServer复制需要有实际的服务器名称才能连接到服务器,请指定实际的服务器名

    最近在学习SQL SERVER的高级复制技术的时候,遇到一个小问题,就是用本地SQL SERVER连接服务器的数据库时,在查看复制功能的发布服务器时,连接不上,弹出一个错误提示框架,如下: 原来在自己 ...

  9. vs code打开文件显示的中文乱码

    这种情况下,一般是编码格式导致的,操作办法: 鼠标点击之后,上面会弹出这个界面,双击选中 然后从UTF-8换到GB2312,或者自己根据情况,更改编码格式

  10. windows10+apache2.4+python3.6部署Django2.2.4项目

    刚从家回来,老师让写专利,就开始准备写,初稿交给老师后,把我说了一顿,我就想着回去改呀,然后...老师找到了我,说是食品院那急需一个展示数据的平台,然我尽快干出来,我也是菜鸟啊,就没单独干过呀,即使是 ...