之前的文章中,我们说过变量赋值的问题,其中有一个问题是对象在进行变量赋值的时候,直接就是引用赋值。那么到底真实情况是怎样呢?

之前变量赋值的文章

PHP的变量赋值

对象引用测试

在继续深入的学习PHP手册后,发现原来对象还真不是直接的引用复制。通过下面手册中的例子来进行分析:

class SimpleClass
{} $instance = new SimpleClass(); $assigned = $instance;
$reference = &$instance; $instance->var = '$assigned will have this value'; $instance = null; // $instance and $reference become null var_dump($instance);
var_dump($reference);
var_dump($assigned);
  • $instance是实例化后的SimpleClass对象
  • $assigned直接赋值
  • $reference引用赋值
  • 首先,我们给$instance对象定义了一个变量var
  • 然后将$instance赋值为null
  • 对于引用来说,$reference变量自然也为成了null
  • 但是$assigned并没有变成null,它依然是SimpleClass的实例对象,并且,划重点哦:它有了var属性

是不是很神奇,照理说,普通赋值是拷贝,两个变量不会相互影响。而引用赋值是复制指针(相同的内存地址),修改任意一个变量其他的变量也会改变。但是对象的普通赋值貌似并不属于它们中的任何一个。

$reference很好理解,本身使用&符号进行了赋值,表明了这个变量是一个引用赋值。它成为了$instance的快捷方式,$instance的一切变化它都都会跟着改变。这是变量层面的。

$assigned从代码字面上看是一个普通赋值。不过对象是一种特殊的形态,它用普通赋值赋过来的值其实是对象的一个句柄。在PHP手册中有一个Note是如此描述的:

首先,将PHP中的变量看成是一个一个的数据槽。这个数据槽可以保存一个基本类型(int、string、bool等)。创建引用时,这个槽里保存的是内存地址,或者说是指向引用对象的一个指针,引用没有拷贝操作,仅仅是将指针指向了原变量(参考数据结构)。创建普通赋值时,则是拷贝的基本类型。

而对象则与基本类型不同,它不能直接保存在数据槽中,而是将对象的“句柄”保存在了数据槽。这个句柄是指向对象特定实例的标识符。虽然句柄不是我们所能直观操作的类型,但它也属于基本类型。

当你获取一个包含对象句柄的变量,并将其分配给另一个变量时,另一个变量获取的是这个对象的句柄。(注意,不是引用!不是引用!不是引用!!)。通过句柄,两个变量都可以修改同一个对象。但是,这两个变量并没有直接关系,它们是两个独立的变量,其中一个变量修改为其他值时,并不会对另一个变量产生影响。只有该变量在修改对象内部的内容时,另一个变量因为持有相同的句柄,所以它的对象内容也会相应地发生改变。

Note原文:

https://www.php.net/manual/zh/language.oop5.basic.php#79856

总结

通过本文的分析,我们可以看出,变量赋值说白了就是变量层面的操作。它保存的永远只是一个值而已。当普通赋值时,这个值就是一个基本类型。当引用赋值时,这个保存的基本类型就是一个指针。不管怎么样,它也不会因为保存的是对象而将普通赋值直接转变为引用赋值,真正的引用赋值是必须要加&符的。

这个内容有点绕,不过这样的内容才能更体现自己的核心能力。读书百遍其义自现,对于手册中的很多知识本人也是来回不断学习才能理解。上面的Note作者写得非常好,英文好的朋友可以直接去看英文原版。

测试代码:

https://github.com/zhangyue0503/dev-blog/blob/master/php/201911/source/%E5%AF%B9%E8%B1%A1%E8%B5%8B%E5%80%BC%E5%9C%A8PHP%E4%B8%AD%E5%88%B0%E5%BA%95%E6%98%AF%E4%B8%8D%E6%98%AF%E5%BC%95%E7%94%A8%EF%BC%9F.php

参考文档:

https://www.php.net/manual/zh/language.oop5.basic.php

关注公众号:【硬核项目经理】获取最新文章

添加微信/QQ好友:【xiaoyuezigonggong/149844827】免费得PHP、项目管理学习资料

知乎、公众号、抖音、头条搜索【硬核项目经理】

B站ID:482780532

对象赋值在PHP中到底是不是引用?的更多相关文章

  1. WeakHashMap<K,V> 中的弱引用

    相信很多人对WeakHashMap并没有完全理解. WeakHashMap 持有的弱引用的 Key. 1. 弱引用的概念: 弱引用是用来描述非必需对象的,被弱引用关联的对象只能生存到下一次垃圾收集发生 ...

  2. Java中到底是值传递还是引用传递?

    Java中到底是值传递还是引用传递? 我们先回顾一下基本概念 实参和形参 参数在编程语言中是执行程序需要的数据,这个数据一般保存在变量中.在Java中定义一个方法时,可以定义一些参数, 举个例子: p ...

  3. Java中到底有没有指针;同时注意引用和指针的区别

    Java中引用的作用类似于指针,但是有区别:()    (1) 指针必然指向一个内存地址,如果你定义的时候不指定,就会乱指(很可能造成安全隐患)但是引用定义出来后默认指向为空.     (2) 指针可 ...

  4. Python中的变量引用对象需注意的几点

    Python中的变量引用对象需注意的几点 分类:Python (55)  (0) 普通引用: Python中,变量的作用仅仅是一个标识,只有赋值后才被创建,它可以引用任何类型的对象,而且在引用之前必须 ...

  5. Java中子类对象赋值给父类变量

    1. 在Java中将一个字类对象赋值给父类变量是合法的,这也是实现多态(即方法的动态分派)的前提条件之一. 2. 在Java中父类赋值同样也适用于数组.可以将一个子类数组赋值给一个父类数组变量.但可能 ...

  6. 详解Java中对象的软、弱和虚引用的区别

    对于大部分的对象而言,程序里会有一个引用变量来引用该对象,这是最常见的引用方法.除此之外,java.lang.ref包下还提供了3个类:SoftReference.WeakReference和Phan ...

  7. php中对象赋值问题

    今天遇到一个问题, 一开始拼接的SQL语句,然后想多次使用时发现会被重置,然后想到给重新赋值一次,但是发现这样赋值会出问题,百思不得其解,最后经过搜索,发现PHP中对象赋值给一个变量之类的赋值的其实是 ...

  8. Struts2的表单标签还可以为集合中的对象赋值

    •Struts 还允许填充 Collection 里的对象, 这常见于需要快速录入批量数据的场合   代码如下 : TestCollectionAction.java package com.atgu ...

  9. using 中写 return 一样会释放using 中对象 但是会在外面定义一个一样的对象 赋值后 释放 最后 return 外面定义的那个对象

    static DataTable getDataTable() { ")) { SqlCommand com = new SqlCommand("", con); Sql ...

随机推荐

  1. HandlerInterceptor与WebRequestInterceptor的异同

    相同点 两个接口都可用于Contrller层请求拦截,接口中定义的方法作用也是一样的. //HandlerInterceptor boolean preHandle(HttpServletReques ...

  2. DG:11.2.0.4 RAC在线duplicate恢复DG

    1.环境介绍 测试环境, 在一个双节点的RAC上使用duplicate搭建DG,使用在线的方式搭建 主机 IP 操作系统 实例 db_name db_unique_name db_version 配置 ...

  3. 06.SpringBoot核心技术

    目录 一.配置文件 二.Web开发 静态资源访问 欢迎页支持 自定义 Favicon 普通参数和基本注解 1.1 @PathVariable 1.2 @RequestHeader 1.3 @Reque ...

  4. NOIP 模拟 $32\; \rm Six$

    题解 二维状压. 第一维直接压选不同质因子的方案,第二位压方案. 分两种讨论,显然一种方案最多出现两次,否则就不合法了,所以一种是出现了一次的,另一种是出现了两次的,这样可以减小状态数. 实现可以用 ...

  5. Anaconda Pycharm 是怎么个事儿?

    前言 许多人学习Python的经历可能很相似,写程序没有问题,最后却被各种环境困扰. 不论你是Python小白,还是学习Python有一段时间了.都可以认真的看一下ヾ(≧▽≦*)o 这篇文章让你对An ...

  6. vs2019编写c++的静态链接库并自己使用

    参考网址:https://blog.csdn.net/flame333/article/details/108346305 静态链接库1.新建一个静态库项目,其中有两个头文件,两个源文件 其中比较重要 ...

  7. 【转】时冲的CSDN:Linux系统各个目录的作用

    请各位移步原文链接:时冲的CSDN 以下仅用于个人梳理,排版方便阅读记忆(原文更优): from my typora: 文章目录 Linux文件系统 LINUX有四种基本文件系统类型: 1.普通文件: ...

  8. 模拟文件上传(二):使用apache fileupload组件进行文件上传

    其中涉及到的jar包: jsp显示层: <%@ page language="java" import="java.util.*" pageEncodin ...

  9. JavaWeb之文件上传、下载

    时间:2016-12-17 18:07 --文件上传概述上传不能使用BaseServlet1.文件上传的作用    例如网络硬盘,就是用来上传和下载文件的.2.文件上传对表单的限制    1)必须使用 ...

  10. VS code快速创建vue模板

    忘记了.vue文件的格式或者不想手动敲那段模板代码怎么办?VS code快速创建vue模板帮你偷个小懒 第一步:新建模板并保存 打开 VS code,依次点击 file > Preference ...