热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PHP7中Reference有什么用

这期内容当中小编将会给大家带来有关PHP7中Reference有什么用,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。try

这期内容当中小编将会给大家带来有关PHP7中Reference有什么用,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

try_again:
swtich (Z_TYPE_P(zv)) {
   case IS_TRING:
   break;
   case IS_ARRAY:
   break;
  ...
   case IS_REFERENCE:
   zv = Z_REFVAL_P(zv); //解引用
   goto try_again;
   break;
}

如果大家自己写的扩展, 如果忘了考虑这种新的类型, 那么就会导致问题.

为什么?
那么既然这种新类型会带来这么多问题, 那么当时为什么要用把引用变成一种类型呢? 为什么不还是使用一个标志位呢?

一句话来说, 就是我们不得不这么做. -_#

前面说到, Hashtable直接存储的是zval, 这样在符号表中, 俩个zval如何共用一个数值呢? 对于字符串等复杂类型来说还好, 我们貌似可以在zend_refcounted结构中加入一个标志位来表明是引用来解决, 然而这个也会遇到Change On Write带来的复制, 但是我们知道在PHP7中, 一些类型是直接存储在zval中的, 比如IS_LONG, 但是引用类型是需要引用计数的, 那么对于一个是IS_LONG并且又是IS_REFERNCE的zval该如何表示呢?

为此, 我们创造了这个新的类型:

PHP7中Reference有什么用

 如图所示, 引用是一种新的类型:zend_reference, 对于IS_REFERNCE类型的zval, zval.value.ref是一个指向zend_reference的指针, 它包含了引用计数和一个zval, 具体的zval的值是存在zval.value.ref->val中的.

所以对于IS_LONG的引用来说, 就用一个类型是IS_REFERNCE的zval, 它指向一个zend_reference, 而这个zend_reference->val中是一个类型为IS_LONG的zval.

Change On Write
PHP采用引用计数来做简单的垃圾回收, 考虑如下的代码:

$ref和$val是指向同一个zval的引用, 在PHP5的时候, 我们是通过一个引用计数为2, 并且引用标志位为1来表示这种情况, 当把$val复制给$copy(line 3)的时候, 我们发现$val是一个计数大于1的引用, 所以要产生Change on write, 也就是分离. 所以我们需要复制这个zval.

而在PHP7中, 情况就变得简单了很多, 首先在引用赋值给$ref(line 2)的时候, 生成一个IS_REFERNCE类型, 然后因为此时有俩个变量引用它所以zend_reference这个结构的引用计数zval.value.ref->gc.refcount为2.

再随后的赋值给$copy(line 3)的时候, 发现$val是一个引用, 于是让$copy指向的是zval.value.ref->val, 也就是字符串值为laruence的zval, 然后把zval的引用计数+1, 也就是zval.value.ref->val.value.str.gc.refcount为2. 并没有产生复制.

从而这就很好的解决了上一章所说的PHP5的那个经典的问题, 比如我们在PHP7下运行上一章的那个问题, 我们得到的结果是:

$ php-7.0/sapi/cli/php /tmp/1.php
Used 0.00021380008539
Used 0.00020173048281

上述就是小编为大家分享的PHP7中Reference有什么用了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注编程笔记行业资讯频道。


推荐阅读
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 本文介绍了在Ubuntu 11.10 x64环境下安装Android开发环境的步骤,并提供了解决常见问题的方法。其中包括安装Eclipse的ADT插件、解决缺少GEF插件的问题以及解决无法找到'userdata.img'文件的问题。此外,还提供了相关插件和系统镜像的下载链接。 ... [详细]
  • windows下安装php7的方法
    windows下安装php7的方法?这个问题可能是我们日常学习或工作经常见到的。希望通过这个问题能让你收获颇深。下面是小编给大家带来的参考内容,让 ... [详细]
  • php7安装pdo_oci扩展的方法
    小编给大家分享一下php7安装pdo_oci扩展的方法,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!php7安装pdo_oci扩展的方法:1 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • MACElasticsearch安装步骤及验证方法
    本文介绍了MACElasticsearch的安装步骤,包括下载ZIP文件、解压到安装目录、启动服务,并提供了验证启动是否成功的方法。同时,还介绍了安装elasticsearch-head插件的方法,以便于进行查询操作。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 本文讨论了微软的STL容器类是否线程安全。根据MSDN的回答,STL容器类包括vector、deque、list、queue、stack、priority_queue、valarray、map、hash_map、multimap、hash_multimap、set、hash_set、multiset、hash_multiset、basic_string和bitset。对于单个对象来说,多个线程同时读取是安全的。但如果一个线程正在写入一个对象,那么所有的读写操作都需要进行同步。 ... [详细]
  • 如何解决MySQL8.0和PHP7不兼容问题
    如何解决MySQL8.0和PHP7不兼容问题?其实要解决这个问题也不难,为此小编总结了这篇文章,下面我们一起来看看解决MySQL8.0和PHP7不兼容的方法。MySQL8 ... [详细]
author-avatar
Andiry舍甫琴科
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有