php 对象克隆 clone

2023-05-16

php 对象复制,是复制对象的引用地址,因此使用 $objA = $objB 这种写法时,$objA与$objB会指向相同的内存地址。当$objA 发生变化时,$objB也会受到影响。
如果我们要$objA对象复制为$objB对象,复制之后,$objA有什么变化,都不会影响$objB。即$objA与$objB是两个独立的对象,但$objB的初始值是由$objA创建的,比较高效的做法是使用clone()方法。
$objB = clone $objA;
$objB的值是在$objA基础加$objA事例对象里clone()方法改变后的实例。
当对象被复制后,所有的属性中的引用保持不变,指向原来的变量,如果定义了__clone()方法,则新创建的对象中的__clone()方法会被调用,可用于修改属性的值。

例子1:clone 对象

<?php
class subclass{

	private $name;
	private $age;

	public function __construct(){
		$this->name = 'fdipzone';
		$this->age = '30';
	}

	public function __clone(){
		$this->name = 'xfdipzone';
		$this->age = '29';
	}

}


class myclass{

	public $p1;
	public $p2;

	public function __construct(){

	}

	public function __clone(){
		$this->p1 = clone $this->p1;
	}

}

$obj = new myclass();
$obj->p1 = new subclass();
$obj->p2 = new subclass();

$obj2 = clone $obj;

echo '<pre>';
echo 'obj<br>';
var_dump($obj);
echo '<br>obj2<br>';
var_dump($obj2);
echo 'ok';
echo '</pre>';

?>
上例将输出:
obj
object(myclass)#1 (2) {
  ["p1"]=>
  object(subclass)#2 (2) {
    ["name":"subclass":private]=>
    string(8) "fdipzone"
    ["age":"subclass":private]=>
    string(2) "30"
  }
  ["p2"]=>
  object(subclass)#3 (2) {
    ["name":"subclass":private]=>
    string(8) "fdipzone"
    ["age":"subclass":private]=>
    string(2) "30"
  }
}

obj2
object(myclass)#4 (2) {
  ["p1"]=>
  object(subclass)#5 (2) {
    ["name":"subclass":private]=>
    string(9) "xfdipzone"
    ["age":"subclass":private]=>
    string(2) "29"
  }
  ["p2"]=>
  object(subclass)#3 (2) {
    ["name":"subclass":private]=>
    string(8) "fdipzone"
    ["age":"subclass":private]=>
    string(2) "30"
  }
}
可以见到,$obj2 clone $obj,$obj->p1 clone $obj->p1,执行了 __clone()方法。而在__clone方法中,对p1的name与 age属性进行修改,因此p1的name与age 发生变化。而p2因为没有执行clone()方法,所以新复制出来的$obj2->p2的属性与 $obj->p2一样。

例子2:clone对象,但部分属性引用保持不变。

<?php

class myclass{

	public $num = null;
	public $msg = null;

	public function __construct(){
		$this->num = & $this->num;
		$this->msg = 'OK';
	}

	public function __clone(){
		$this->num = 2;	
	}
}

$obj = new myclass();
$obj->num = 1;

echo 'print obj values<br>';
var_dump($obj);
echo '<br><br>';

$obj2 = clone $obj;

echo 'clone obj to obj2<br>';
echo 'obj->num:'.$obj->num.'<br>';
echo 'obj->msg:'.$obj->msg.'<br>';
echo 'obj2->num:'.$obj2->num.'<br>';
echo 'obj2->msg:'.$obj2->msg.'<br><br>';

$obj2->num = 3;
$obj2->msg = 'Yes';

echo 'set obj2->num=3, obj2->msg=Yes<br>';
echo 'obj->num:'.$obj->num.'<br>';
echo 'obj->msg:'.$obj->msg.'<br>';
echo 'obj2->num:'.$obj2->num.'<br>';
echo 'obj2->msg:'.$obj2->msg.'<br><br>';

?>
上例将输出:
print obj values
object(myclass)#1 (2) { ["num"]=> &int(1) ["msg"]=> string(2) "OK" }

clone obj to obj2
obj->num:2
obj->msg:OK
obj2->num:2
obj2->msg:OK

set obj2->num=3, obj2->msg=Yes
obj->num:3
obj->msg:OK
obj2->num:3
obj2->msg:Yes
因$this->num = &$this->num,因此clone()之后,新对象的$this->num都是引用旧对象的内存地址。因此旧对象这个属性发生变化,新对象这个属性也会发生变化,实现了某些属性的引用保持不变。
而$this->msg并不是地址引用,因此,新对象的msg发生变化,不会影响到旧对象。


注意:$this->num = & $this->num 使用对象属性地址引用时,在clone之前不能echo/print这个属性,否则地址引用会失效。

上例中,如果在$obj2 = clone $obj前加上,echo $obj->num; 则会使地址引用实效,即$obj2->num发生改变,$obj->num并不会发生改变。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

php 对象克隆 clone 的相关文章

  • WSL2 更换硬盘位置

    windows wsl子系统默认硬盘存放位置在c盘 xff0c 想要换到其他盘 1 关闭wsl wsl shutdown 2 查看wsl信息 wsl l v NAME STATE VERSION Debian Stopped 2 Ubunt
  • ubuntu鼠标灵敏度、加速度修改

    一直觉得ubuntu的鼠标指针比较飘 xff0c 图形界面上调整灵敏度调到最低也不准 xff0c 因为鼠标设置里面没有提供其他可调整选项 xff0c 目前找到一个解决办法是调整鼠标加速度 各版本调整方法链接 xff1a https patr
  • 使用apt-mirror搭建ubuntu本地安装源

    环境 xff1a 使用一台ubuntu 16 04作为服务器 1 建立文件 mkdir data mkdir data 16 04 mkdir data 16 04 mirror mkdir data 16 04 var mkdir dat
  • 三角函数关系图

    倒三角关系 s i n 2 x
  • 关于打开虚拟机VMware centos7之后就蓝屏的解决办法

    装完镜像之后 xff0c 打开虚拟机 xff0c 一开机就蓝屏 解决办法 xff1a VMware 版本太低 xff0c 下载新版VMware 可以解决大部分问题
  • n个数输出最大值和最小值

    提型描述 xff1a 输入整数N xff0c 接着在下一行连续输入N个数 xff0c 输出这一组数的最大值和最小值 xff1b 提示 xff1a 输入的这N个数 xff0c 可以有小数也可以有负数 xff0c 输出之间用换行隔开 inclu
  • java求完数的代码

    用java求完数 xff1a 题目 xff1a 一个数如果恰好等于它的真因子 即不包括它本身 之和 xff0c 这个数就称为 34 完数 34 例如6 61 1 xff0b 2 xff0b 3 请编程找出1000以内的所有完数 代码如下 x
  • libc++abi Specification

    void cxa allocate exception size t thrown size throw Effects Allocates memory to hold the exception to be thrown thrown
  • Java:利用递归方法求鸭子数

    问题描述 xff1a 一个人赶着鸭子去每个村庄卖 xff0c 每经过一个村子卖去所赶鸭子的一半又一只 这样他经过了七个村子后还剩两只鸭子 xff0c 问他出发时共赶多少只鸭子 xff1f 经过每个村子卖出多少只鸭子 xff1f 题目分析 x
  • 登录授权验证之OAuth2.0

    实际应用项目 xff1a http github crmeb net u long 本文将从几个方面了解和学习使用OAuth2 0 对不对就不管了 xff0c 反正我也几乎不会用到 ps 有个项目用到了 xff0c 所以才会有本文 OAut
  • PostgreSQL的视图以及物化视图的特点

    1 视图 PostgreSQL视图其实和mysql视图是一样的 xff0c 视图其实是个虚拟的表 xff0c 实际上是一个SQL拼接而成的虚拟表 xff08 假表 xff09 xff0c 可能是有一个表或者多个表 视图关联而成的复杂的SQL
  • 尚硅谷---Vue3同步笔记

    一 初识Vue3 Vue3带来了什么 xff1f 1 性能上的提升 xff1a 更快 占用内存更少 2 源码的升级 xff1a 使用Proxy代替defineProperty实现响应式 重写虚拟DOM的实现和Tree Shaking Tre
  • 移动mgv2000_JL代工_s905l2_MT7668_emmc_免拆卡刷固件包

    移动mgv2000 JL代工 s905l2 MT7668 emmc 免拆卡刷固件包 特点 xff1a 1 适用于卡刷 xff1b 2 开放原厂固件屏蔽的市场安装和u盘安装apk xff1b 3 修改dns xff0c 三网通用 xff1b
  • 魔百和CM311-1A_YST、(YM)_安卓9_S905L3A_默认开启ADB_纯净精简语音_完美线刷包

    魔百和CM311 1A YST YM 安卓9 S905L3A 默认开启ADB 纯净精简语音 完美线刷包 固件特点 xff1a 1 修改dns xff0c 三网通用 xff1b 2 开放原厂固件屏蔽的市场安装和u盘安装apk xff1b 3
  • C++11:变长模板的迭代与递归扩展

    迭代的运行效率始终强于递归 xff0c 递归始终比迭代方便开发 变长模板属于C 43 43 11中比较复杂的技术 xff0c 在此简单介绍下 include lt iostream gt using namespace std templa
  • 虚拟机Secure Boot安全启动

    概述 Secure Boot 作为 UEFI 的一个选项 xff0c 它可以被设置为开启或关闭 Secure Boot 所需要的公钥证书被保存在计算机的主板的 FLASH 里面 xff0c FLASH 里面保存着 PK xff0c KEK
  • 端口被占用的原因及解决办法

    运行软件或者项目的时候 xff0c 出现以下问题 xff1a panic blademaster listen tcp 0 0 0 0 8080 listen tcp 0 0 0 0 8080 bind An attempt was mad
  • Rust 学习,与 node.js 交互

    1 背景 近期 xff0c 参与了一个活动 xff1a 学 Rust xff0c 免费拿树莓派 主要内容为开发应用 xff0c 在 node js 中调用 Rust 函数 实际上我认为在很多地方都能用上 Rust xff0c 鉴于活动要求
  • Zeal--一款支持207个离线文档的浏览器

    小编作为一个全栈工程师 xff0c 每个语言都会一点 xff0c 在写前端和后端的时候 xff0c 时长会打开好几个开发文档 xff0c 比如java css html 等 xff0c 有没有打开一个软件 xff0c 就能打开所有的帮助文档
  • Linux之间图像界面的传输 ssh -X username@{remote ip}

    之前用windows平台连接Linux平台 xff0c 总是通过Xshell 43 Xming来传输Linux系统的界面 现在在linux系统平台下 xff0c 通过ssh连接另一个Linux系统 xff0c 如何将远程Linux的图形界面

随机推荐

  • 利用图片Etag判断用户

    原理 xff1a 不使用Javascript xff0c SESSION xff0c COOKIES xff0c FLASH 利用图片Etag识别用户 1 根据用户的 REMOTE ADDR 与 HTTP USER AGENT 生成唯一Et
  • 音视频基础知识---封装格式介绍

    音视频基础知识汇总 xff1a 音视频基础知识 协议相关RTSP RTMP HLS 音视频基础知识 封装格式 音视频基础知识 视频编码格式 音视频基础知识 音频编码格式 音视频基础知识 像素格式RGB 音视频基础知识 像素格式YUV 1 什
  • php output_buffering 缓存使用

    buffer是一个内存地址空间 xff0c linux系统默认大小一般为4096 4kb 主要用于存储速度不同步的设备或优先级不同的设备之间传递数据的区域 通过buffer可以使进程之间的相互等待变少 例如 xff0c 当你打开一个文本编辑
  • 同一域名对应不同IP,访问指定主机文件内容的方法

    PHP获取远程主机文件内容方法很多 xff0c 例如 xff1a file get contents xff0c fopen 等 lt php echo file get contents 39 http demo fdipzone com
  • php 实现BigPipe分块输出

    原理 xff1a 利用 ob flush 与 flush 将缓冲区的内容提前输出 xff0c 浏览器可提早加载这部分的内容 xff0c 无需等待所有输出完成再加载 将页面内容划分为一个个小块 xff0c 输出一个后再输出下一个 xff0c
  • php 利用fsockopen GET/POST 提交表单及上传文件

    php 利用 fsockopen GET POST 提交表单及上传文件 1 GET get php lt php host 61 39 demo fdipzone com 39 port 61 80 errno 61 39 39 errst
  • php 过滤html标记属性类

    php 过滤html标记属性类 HtmlAttributeFilter class php lt php HTML Attribute Filter Date 2013 09 22 Author fdipzone ver 1 0 Func
  • php HTTP请求类,支持GET,POST,Multipart/form-data

    PHP HTTP请求类 xff0c 支持GET POST Multipart form data HttpRequest class php lt php HttpRequest class HTTP请求类 xff0c 支持GET POST
  • HTTP 204 与 205 应用

    HTTP 204 no content 表示响应执行成功 xff0c 但没有数据返回 xff0c 浏览器不用刷新 xff0c 不用导向新页面 HTTP 205 reset content 表示响应执行成功 xff0c 重置页面 xff08
  • apache mod_xsendfile 让php提供更快的文件下载

    服务器提供一个文件下载 xff0c 一般使用一个url指向服务器中的文件即可提供下载 但这样就不能进行统计 xff0c 权限检测等操作 因此 xff0c 一般使用php提供下载 xff0c 代码如下 xff1a lt php file 61
  • HTML5 使用application cache 接口实现离线数据缓存

    1 配置缓存文件 cache manifest MIME TYPE xff1a text cache manifest 文件名称 xff1a name appcache 作用 xff1a 用于配置需要缓存的文件 2 使用方法 在服务器上添加
  • XSS跨站测试代码大全

    XSS跨站测试代码大全 39 gt lt script gt alert document cookie lt script gt 61 39 gt lt script gt alert document cookie lt script
  • 范数、神秘值

    范数 格式 xff1a n 61 norm A p 功能 xff1a norm函数可计算几种不同类型的矩阵范数 依据p的不同可得到不同的范数 下面是Matlab中help norm 的解释 NORM Matrix or vector nor
  • anaconda3 安装(自用,记录用)

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 目录 前言 一 anaconda 卸载 二 anaconda3安装 1 Anaconda下载 2 Anaconda配置 三 Anacond
  • mysql 优化 insert 性能

    mysql 的 insert 语句语法 insert into 96 table 96 96 field1 96 96 field2 96 values 39 value1 39 39 value2 39 提高insert 性能的方法 1
  • 使用onbeforeunload事件检测窗口是否刷新或关闭

    onunload xff0c onbeforeunload 在页面刷新或关闭时调用 xff0c 区别在于 xff1a onbeforeunload 是在页面刷新或关闭前触发 xff0c 这时浏览器并未请求服务器读取新页面 xff0c 因此o
  • php 使用异或(XOR)加密/解密文件

    php 使用异或 xff08 XOR xff09 加密 解密文件 原理 xff1a 将文件每一个字节与key作位异或运算 xff08 XOR xff09 xff0c 解密则再执行一次异或运算 代码如下 xff1a lt php source
  • php 如何获取一个变量的名字

    PHP中 xff0c 所有的变量都存储在 34 符号表 34 的HastTable结构中 xff0c 符号的作用域是与活动符号表相关联的 因此 xff0c 同一时间 xff0c 只有一个活动符号表 我们要获取到当前活动符号表可以通过 get
  • PHP扩展开发报错解决[error: ‘PHP_FE_END’ undeclared here (not in a function)] .

    PHP扩展开发报错解决 error PHP FE END undeclared here not in a function 解决方法 xff1a 进到php包的目录 sed i 39 s PHP FE END NULL NULL NULL
  • php 对象克隆 clone

    php 对象复制 xff0c 是复制对象的引用地址 xff0c 因此使用 objA 61 objB 这种写法时 xff0c objA与 objB会指向相同的内存地址 当 objA 发生变化时 xff0c objB也会受到影响 如果我们要 o