博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
彻底搞懂 PHP 变量结构体,多数文章观点不准确
阅读量:7068 次
发布时间:2019-06-28

本文共 2872 字,大约阅读时间需要 9 分钟。

PHP5 中的 zval

// 1. zvaltypedef struct _zval_struct {
zvalue_value value; zend_uint refcount__gc; zend_uchar type; zend_uchar is_ref__gc;} zval;// 2. zvalue_valuetypedef 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;// 3. zend_object_valuetypedef struct _zend_object_value {
zend_object_handle handle; const zend_object_handlers *handlers;} zend_object_value;// 4. zend_object_handletypedef unsigned int zend_object_handle;复制代码

多数文章,在提到PHP5 变量结构体的时候,都提到:sizeof(zval) == 24, sizeof(zvalue_value) == 16,实际上这个论述并不准确,在 CPU 为 64bit 时,这个结果是正确的。

但当 CPU 为32bit 时: sizeof(zval) == 16, sizeof(zvalue_value) == 8,主要因为 CPU 为 64bit 时,指针占用8个字节,而 32bit时,指针为4个字节。

PHP 7 中的 zval

// 1. zvalstruct _zval_struct {
zend_value value; /* value */ union { struct {
ZEND_ENDIAN_LOHI_4( zend_uchar type, /* active type */ zend_uchar type_flags, zend_uchar const_flags, zend_uchar reserved) /* call info for EX(This) */ } v; uint32_t type_info; } u1; union { uint32_t next; /* hash collision chain */ uint32_t cache_slot; /* literal cache slot */ uint32_t lineno; /* line number (for ast nodes) */ uint32_t num_args; /* arguments number for EX(This) */ uint32_t fe_pos; /* foreach position */ uint32_t fe_iter_idx; /* foreach iterator index */ uint32_t access_flags; /* class constant access flags */ uint32_t property_guard; /* single property guard */ } u2;};// 2. zend_valuetypedef union _zend_value { zend_long lval; /* long value */ double dval; /* double value */ zend_refcounted *counted; zend_string *str; zend_array *arr; zend_object *obj; zend_resource *res; zend_reference *ref; zend_ast_ref *ast; zval *zv; void *ptr; zend_class_entry *ce; zend_function *func; struct {
uint32_t w1; uint32_t w2; } ww;} zend_value;复制代码

PHP 7的看似很多,但其实更简单了,不论 CPU 是32bit 还是 64bit,sizeof(zval) 永远都是等于 16。

主要看 zend_value 中的 ww,是两个 uint32_t,这个永远是 8 个字节,所以 sizeof(zend_value) == 8,因此 sizeof(zval) == 16。

所以 PHP7 新特性提到的节省内存这点上,在 32bit 系统中,PHP5 => PHP7 并无变化。

顺便说下 sizeof,不能当做函数,虽然写法像函数,这个数值会在编译期就确定好,非运行期。类似编译预处理。

有关sizeof的详情,可以看:

这个CSDN 文章的排版虽然有些乱,但总结的都是精华,耐心看完,理解透彻后,就很容理解我上面的分析。

原文:

转载于:https://juejin.im/post/59df252c6fb9a04500020c0b

你可能感兴趣的文章
rails 遇到问题 记录
查看>>
Java数组与内存控制
查看>>
索引的一些总结【转】
查看>>
pku 1019 Number Sequence 组合数学 找规律
查看>>
MySQL实用语句 GROUP BY ... HAVING ...
查看>>
高性能网站性能优化与系统架构(ZT)
查看>>
【转】每天一个linux命令(10):cat 命令
查看>>
Python——dummy_thread( _dummy_thread in Python 3.+)
查看>>
关于逻辑运算符书写效率问题 和数组 处理问题
查看>>
【web开发学习笔记】Structs2 Result学习笔记(一)简介
查看>>
android studio中取消关联git
查看>>
Mysql的共享锁和排他锁(转载)
查看>>
Preemption Context Switches 和 Synchronization Context Switches
查看>>
UVA 10405 Longest Common Subsequence (动态规划 LCS)
查看>>
CURL常用命令
查看>>
阿里巴巴技术团队博客
查看>>
java 单例模式
查看>>
IIS8 使用FastCGI配置PHP环境支持 过程详解
查看>>
互联网TCP/IP五层模型(一)
查看>>
ftrace 简介【转】
查看>>