(点击上方公众号,可快速关注我们)

英文:Nikita Popov

中文:Scholer(@Scholer-L)

链接:http://0x1.im/blog/php/Internal-value-representation-in-PHP-7-part-1.html

本文第一部分和第二均翻译自Nikita Popov(nikic,PHP 官方开发组成员,柏林科技大学的学生) 的博客。为了更符合汉语的阅读习惯,文中并不会逐字逐句的翻译。

要理解本文,你应该对 PHP5 中变量的实现有了一些了解,本文重点在于解释 PHP7 中 zval 的变化。

由于大量的细节描述,本文将会分成两个部分:第一部分主要描述 zval(zend value) 的实现在 PHP5 和 PHP7 中有何不同以及引用的实现。第二部分将会分析单独类型(strings、objects)的细节。

PHP5 中的 zval

PHP5 中 zval 结构体定义如下:

typedef struct _zval_struct {

zvalue_value value;

zend_uint refcount__gc;

zend_uchar type;

zend_uchar is_ref__gc;

} zval;

如上,zval 包含一个 value、一个 type 以及两个 __gc 后缀的字段。value 是个联合体,用于存储不同类型的值:

typedef union _zvalue_value {

long lval; // 用于 bool 类型、整型和资源类型

double dval; // 用于浮点类型

struct { // 用于字符串

char *val;

int len;

} str;

HashTable *ht; // 用于数组

zend_object_value obj; // 用于对象

zend_ast *ast; // 用于常量表达式(PHP5.6 才有)

} zvalue_value;

C 语言联合体的特征是一次只有一个成员是有效的并且分配的内存与需要内存最多的成员匹配(也要考虑内存对齐)。所有成员都存储在内存的同一个位置,根据需要存储不同的值。当你需要 lval 的时候,它存储的是有符号整形,需要 dval 时,会存储双精度浮点数。

需要指出的是是联合体中当前存储的数据类型会记录到 type 字段,用一个整型来标记:

#define IS_NULL 0 /* Doesn't use value */

#define IS_LONG 1 /* Uses lval */

#define IS_DOUBLE 2 /* Uses dval */

#define IS_BOOL 3 /* Uses lval with values 0 and 1 */

#define IS_ARRAY 4 /* Uses ht */

#define IS_OBJECT 5 /* Uses obj */

#define IS_STRING 6 /* Uses str */

#define IS_RESOURCE 7 /* Uses lval, which is the resource ID */

/* Special types used for late-binding of constants */

#define IS_CONSTANT 8

#define IS_CONSTANT_AST 9

PHP5 中的引用计数

在PHP5中,zval 的内存是单独从堆(heap)中分配的(有少数例外情况),PHP 需要知道哪些 zval 是正在使用的,哪些是需要释放的。所以这就需要用到引用计数:zval 中 refcount__gc 的值用于保存 zval 本身被引用的次数,比如 $a = $b = 42 语句中,42 被两个变量引用,所以它的引用计数就是 2。如果引用计数变成 0,就意味着这个变量已经没有用了,内存也就可以释放了。

注意这里提及到的引用计数指的不是 PHP 代码中的引用(使用

Tag标签:

php7 变量,变量在PHP7内部的实现(一)相关推荐

  1. php7 定义变量,基于PHP7的PHP扩展开发之七(定义变量)

    目的:熟悉在PHP扩展里面如何定义变量 要实现的PHP代码如下: class lostphp{} $lng = 2; $str = "abc"; $arr = array(1,'a ...

  2. 在python中、实例变量在类的内部通过_[宜配屋]听图阁

    1.类变量.实例变量概念 类变量: 类变量就是定义在类中,但是在函数体之外的变量.通常不使用self.变量名赋值的变量.类变量通常不作为类的实例变量的,类变量对于所有实例化的对象中是公用的. 实例变量 ...

  3. 在python中、实例变量在类的内部通过_【python】类变量、实例变量

    1.类变量.实例变量概念 类变量: 类变量就是定义在类中,但是在函数体之外的变量.通常不使用self.变量名赋值的变量.类变量通常不作为类的实例变量的,类变量对于所有实例化的对象中是公用的. 实例变量 ...

  4. 静态变量、动态变量、内部变量(局部变量)、外部变量(全局变量)

    区分静态变量.动态变量.内部变量(局部变量).外部变量(全局变量) 静态变量.动态变量.内部变量(局部变量).外部变量(全局变量) 变量的分类来看 静态变量.动态变量.内部变量(局部变量).外部变量( ...

  5. 【Groovy】Groovy 方法调用 ( 字符串切割 | 使用 Java 语法切割字符串 | 使用 Groovy 语法切割字符串直接为变量赋值 | 数组赋值给变量 变量个数小于等于数组长度 )

    文章目录 一.字符串切割 1.使用 Java 语法切割字符串 2.使用 Groovy 语法切割字符串直接为变量赋值 3.数组赋值给变量 变量个数小于等于数组长度 二.完整代码示例 一.字符串切割 在 ...

  6. php7 编译参数详解,php7.4.5编译安装参数变更

    Last updated on 2020年6月11日 php7.3/7.4开始,很多之前的配置取消或者变更了,比如不支持"–with-gd, –with-mcrypt,  –with-lib ...

  7. php7的稳定性,探索PHP7(一)--性能

    #探索PHP7(一)--性能# ##前言## 在2015年12月2号,鸟哥的在开源中国发布的新闻写在 PHP 7 发布之际一些话,小编意识到从8月份发布第一个公测版到现在经过了将近4个月的等待PHP7 ...

  8. java语言语法--- Java标识符(标识符命名规则)、Java关键字、Java变量(变量的声明、赋值、使用)和常量(字符常量、字面常量)(包括Java字节码文件反汇编命令javap)

    java语言语法- Java标识符.Java关键字.Java变量和常量(包括Java字节码文件反汇编命令javap) 1.标识符 (1)读音:biao zhi fu (2)什么是标识符? (摘自百度百 ...

  9. ubuntu 16.04 + apache2 将php7.1 切换到 php7.3

    背景: ubuntu 更新时,选择,保留当前 php 版本,导致出现了 多个php 版本 ,phpinfo 显示的是 php7.1.在用 php -i 查看,发现,很多扩展打不开. 1. Ubuntu ...

  10. 环境变量 变量名 变量值_如何使用环境变量

    环境变量 变量名 变量值 Environment variables are a set of dynamic named values that can affect the way running ...

最新文章

  1. Keepalived双主模型中vrrp_script中权重改变故障排查
  2. 数据库设计中的范式、关联与nosql分析【转】
  3. Internet Explorer 已停止工作 解决办法
  4. aspx页面事件执行顺序
  5. tolowercase_Java String toLowerCase()方法与示例
  6. Tableau BI工具对接 AnalyticDB for PostgreSQL数据源
  7. Failed to parse PID from file /run/nginx.pid: Invalid argument
  8. openresty的安装和使用
  9. ASP.NET 控件与可访问
  10. Linux学习----文件的使者-Rsync(马哥教育原创)
  11. WSL使用史上最详细教程
  12. Universal Radio Hacker(URH):一个用于逆向解析和攻击无线通信协议的开源工具
  13. java 实现阿里云邮箱的发送
  14. bat窗口大小设置_dos命令发出声音图文教程,电脑音箱喇叭蜂鸣器滴,bat批处理脚本...
  15. Java 流行的工作流引擎
  16. Linux Ruby安装
  17. EXCEL如何将平均值加减标准差设置为科学计数法显示
  18. 2020年的成长印记
  19. C语言知识点--define的替换列表为空是怎么回事?
  20. 百度搜索结果左侧图片设置方法

热门文章

  1. 图片爬取数据解析数据持久化
  2. 静态反调试技术(1)
  3. 5、删除用户(DROP/DELETE USER)
  4. 1.7 Character类
  5. Web前端之登录表单
  6. 2021算法竞赛入门班第四节课【搜索】练习题
  7. 催收系统服务器,催收系统安装文档/ 环境搭建 /测试服务器 java工程启动文档
  8. linux之cal命令详解,linux命令大全之cal命令详解(显示日历)
  9. 【数据结构-图】3.图的最短路径的几种算法(图解+演绎)
  10. 遇到一个git的大坑 src refspec master does not match any error: failed to push some refs to