php7内核之zval

本文对应的php版本7.4.3

下载地址:https://www.php.net/downloads

zval是什么

zval是表示php变量的数据结构

每个zval占用多大的空间

一共占16个字节,value占8字节,u1和u2都占4字节。

源码文件地址

php/include/php/Zend/zend_types.h文件

整体结构

struct _zval_struct {
        zend_value        value;                        /* value */
        union {
                struct {
                        ZEND_ENDIAN_LOHI_3(
                                zend_uchar    type,                     /* active type */
                                zend_uchar    type_flags,
                                union {
                                        uint16_t  extra;        /* not further specified */
                                } u)
                } v;
                uint32_t type_info;
        } u1;
        union {
                uint32_t     next;                 /* hash collision chain */
                uint32_t     cache_slot;           /* cache slot (for RECV_INIT) */
                uint32_t     opline_num;           /* opline number (for FAST_CALL) */
                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 */
                uint32_t     constant_flags;       /* constant flags */
                uint32_t     extra;                /* not further specified */
        } u2;
};


主要有value,u1,u2三大块,接下来我们来看下每块对应的结构以及都是做什么的。

value块解析

我们通过追源码发现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;


可以把它理解成类型的集合,你能用到的都在这里。

u1块解析

union {
		struct {
        		ZEND_ENDIAN_LOHI_3(
                		zend_uchar    type,                     /* active type */
                		zend_uchar    type_flags,
                        union {
                        		uint16_t  extra;        /* not further specified */
                        } u)
       } v;
       uint32_t type_info;
} u1;

u1.type:根据type去取value中对应的值,如果我的type是 7,那么他就会去value中去取zend_array,可选值如下

/* regular data types */
#define IS_UNDEF                                        0
#define IS_NULL                                         1
#define IS_FALSE                                        2
#define IS_TRUE                                         3
#define IS_LONG                                         4
#define IS_DOUBLE                                       5
#define IS_STRING                                       6
#define IS_ARRAY                                        7
#define IS_OBJECT                                       8
#define IS_RESOURCE                                     9
#define IS_REFERENCE                            10

/* constant expressions */
#define IS_CONSTANT_AST                         11

/* internal types */
#define IS_INDIRECT                     13
#define IS_PTR                                          14
#define IS_ALIAS_PTR                            15
#define _IS_ERROR                                       15

/* fake types used only for type hinting (Z_TYPE(zv) can not use them) */
#define _IS_BOOL                                        16
#define IS_CALLABLE                                     17
#define IS_ITERABLE                                     18
#define IS_VOID                                         19
#define _IS_NUMBER                                      20

u1.type_flags:对应变量类型特有的标记,比如说引用计数的类型、可能包含循环引用的类型等等,取值如下

/* zval.u1.v.type_flags */
#define IS_TYPE_REFCOUNTED                      (1<<0)
#define IS_TYPE_COLLECTABLE                     (1<<1)

u2块解析

union {
        uint32_t     next;                 /* hash collision chain */
        uint32_t     cache_slot;           /* cache slot (for RECV_INIT) */
		uint32_t     opline_num;           /* opline number (for FAST_CALL) */
		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 */
		uint32_t     constant_flags;       /* constant flags */
		uint32_t     extra;                /* not further specified */
} u2;

u2.next:用来解决hash冲突
u2.cache_slot:用来做运行时缓存
u2.lineno:标记是php的哪一行,一般用在抽象语法树
u2.num_arg:函数调用传入的参数个数
u2.fe_pos:foreach时候它的位置,我们每foreach一次。这个值就会加1
u2.fe_iter_idx:和上面的类似,也是在foreach时使用,代表游标的索引位置
u2.access_flags:用在类里面,比如说我们写代码的时候用到的private、public、protected类型标记就是用的这个字段
u2.property_guard:防止类中魔术方法的循环引用,get和set会用到
u2.constant_flags:常量类型的标记

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值