php7的zval及变量存储方式
2021/12/14 22:18:11
本文主要是介绍php7的zval及变量存储方式,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Zval是PHP中最重要的数据结构之一,它包含了PHP中变量的值和类型相关信息。
1. zval
1.1 zval的结构(zend_types.h)
typedef struct _zval_struct zval; struct _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 var_flags; 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 */ } u2; };
zval结构比较简单, 由三个部分组成:
- zend_value:保存具体变量类型的值或指针
- u1的核心作用是区分类型
- u2为辅助值
为了更直观的看下zval的结构及核心字段的取值,我们上张图。
对u1.v.type的说明:
IS_UNDEF:标记未定义,表示数据可以被覆盖或者删除。比如在对数组元素进行unset操作时,PHP 7并不会直接将数据从分配给HashTable的内存中删掉,而是先将该元素所在的Bucket的位置标记为IS_UNDEF,当HashTable中IS_UNDEF元素个数到达一定阈值时,进行rehash操作时再将IS_UNDEF标记的元素覆盖或删除。
IS_TRUE和IS_FALSE:这里将IS_BOOL优化成两个,直接将布尔类型的标记记录在type中。
IS_REFERENCE:是新增的类型,PHP7中使用不同的处理方式来处理“&”
IS_INDIRECT:同样也是新增的类型,由于PHP 7中HashTable的设计跟PHP5中有很大的不同,所以在解决全局符号表访问CV变量表的问题上,引入了IS_INDRECT类型。
IS_PTR:该类型被定义为指针类型,用来解析value.ptr,通常用在函数类型上。比如声明一个函数或者方法。
1.2 zend_value
zval的中zend_value定义如下:
typedef 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;
1.3 zval内存占用
在一个zval中:
zend_value为union,只占8字节。刚好可以存放一个zend_long或是一个double,又或者一个指针。
u1为4字节,存储一个v或type_info
u2为4字节
所以一个zval占用16字节。相应php5中,一个zval的大小为48字节,的确是巨大的提升。
2. 变量存储
2.1 true, false, null
可根据zval.u1.v.type直接区分,无需zend_value参与
2.2 long,double
直接存储在zend_value的lval或dval中。
2.3 其它类型(string,array,object,resource等)
使用zend_value对应的指针,指向其具体的结构。
比如字串类型的结构为
struct _zend_string { zend_refcounted_h gc; zend_ulong h; /* hash value */ size_t len; char val[1]; };
一个字串变量内存组织如下图所示, zval.value.str指向zend_string结构。
这篇关于php7的zval及变量存储方式的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-19php8的协程和hyperf的协程有什么区别?-icode9专业技术文章分享
- 2024-12-19php8 的fiber是什么?-icode9专业技术文章分享
- 2024-12-05怎么在php8,1 里面开启 debug?-icode9专业技术文章分享
- 2024-12-05怎么在php8,1 里面开启 debug?-icode9专业技术文章分享
- 2024-11-29使用PHP 将ETH账户的资产汇集到一个账户
- 2024-11-23怎么实现安卓+php 热更新方案?-icode9专业技术文章分享
- 2024-11-22PHP 中怎么实现判断多个值是否为空、null 或者为 false?-icode9专业技术文章分享
- 2024-11-11开源 PHP 商城项目 CRMEB 二次开发和部署教程
- 2024-11-09怎么使用php在kaufland平台刊登商品?-icode9专业技术文章分享
- 2024-11-05PHP的抽象类和接口是什么,有什么区别-icode9专业技术文章分享