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. java -jar 和 java -cp 的区别

    https://blog.csdn.net/weixin_38653290/article/details/84647019 1.pom中build指定mainClass 但是 META-INF\MA ...

  2. Java远程调用Linux脚本

    参考:http://blog.csdn.net/xiao_jun_0820/article/details/26254813  http://blog.csdn.net/a19881029/artic ...

  3. 01.Homebrew

    1.homebrew 的安装 ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/ ...

  4. swoole使用异步redis

    1.lnmp安装redis拓展 wget http://download.redis.io/releases/redis-4.0.9.tar.gz chmod 755 redis-4.0.9.tar. ...

  5. visual studio2019下静态链接库的制作

    创建静态库项目 项目名称为20199324lib // pch.h #ifndef __PCH__ #define __PCH__ extern int add(int a, int b);//ext ...

  6. 【lca+输入】Attack on Alpha-Zet

    Attack on Alpha-Zet 题目描述 Space pirate Captain Krys has recently acquired a map of the artificial and ...

  7. SpringMVC配置讲解(一)

    SpringMVC 核心类和接口 DispatcherServlet   -- 前置控制器 在DispatcherServlet的初始化过程中,框架会在web应用的 WEB-INF文件夹下寻找名为[s ...

  8. 三十四、www服务apache进阶

    9.虚拟主机:部署多个站点,每个站点希望用不同的站点域名和站点目录,或者是不同的端口和不同的IP,则需要虚拟主机,简单理解就是一个http服务要配置多个站点,就要虚拟主机. apache虚拟主机分为三 ...

  9. springboot 整合thymeleaf 书笔记

    pom.xml依赖添加 <!--引入thymeleaf--> <dependency> <groupId>org.springframework.boot</ ...

  10. scala slick mysql utf8mb4 支持

    语言  scala sql包  slick 3.2.0 数据库  mysql https://stackoverflow.com/questions/36741141/scala-slick-jdbc ...