美文网首页php源码学习
php7中的zval结构体

php7中的zval结构体

作者: 尤旭 | 来源:发表于2019-03-21 15:20 被阅读0次

php7中的zval结构体对比php5优化了很多,一个zval只占用16字节的空间,php7中的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     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 */
        uint32_t     extra;                /* not further specified */
    } u2;
};

其中value的结构体占用了8个字节,这里面存储的就是zval中的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;
        //zval类型
    void             *ptr;
        //指针类型
    zend_class_entry *ce;
        //class类型
    zend_function    *func;
        //funciton类型
    struct {
        uint32_t w1;
        uint32_t w2;
    } ww;
} zend_value;

其中针对php的各种类型增加了相应的结构体。
在zval结构体中,还有u1和u2,这两个字段记录了其他信息,比较关注的就是u1当中的type是用来标识这个zval的类型。type_info是对应变量的特有标记。
u1中的type类型对应关系为

/* 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                 11
#define IS_CONSTANT_AST             12

/* fake types */
#define _IS_BOOL                    13
#define IS_CALLABLE                 14
#define IS_ITERABLE                 19
#define IS_VOID                     18

/* internal types */
#define IS_INDIRECT                 15
#define IS_PTR                      17
#define _IS_ERROR                   20

用以标识zval数据类型。
比方说 我们php代码中定义一个$a = 1;

<?php
$a = 1;
echo $a;

我们用gdb来实际看下这个变量对应的结构体,在ZEND_ECHO_SPEC_CV_HANDLER打断点来查看。

1553151577345.jpg
其中可以看到打印出来的zval中u1.type为4,4代表IS_LONG类型,这是种简单类型,所以这个值被直接存储到了lval中了。
那么现在如果我们unset了这个$a变量,在来看看这个结构体。
<?php
$a = 1;
unset($a);
echo $a;
WX20190321-150605.png
可以看到这个时候的会把u1.type标识为0,0代表的是IS_UNDEF标记为未使用类型。待之后的垃圾回收机制来收回即可。
现在在来看一个字符串类型,字符串类型在php7中不是一个简单数据类型,他的value值会存储在value.str当中,我们这时候定义如下php代码
<?php
$a = 'a';
echo $a;

在来gdb看下这个zval结构

str1.png
这时候我们打印出来这个value.str看到他是一个zend_string类型的数据
str2.png

这个zend_string结构体在php源码中的定义是这样的

struct _zend_string {
    zend_refcounted_h gc;
    zend_ulong        h;                /* hash value */
    size_t            len;
    char              val[1];
};

我们具体看下他的数值。

str3.png
gc是处理垃圾回收的,h是冗余了一个hash值,是为了在数组操作中避免对于hash值的重复计算,len表示字符串的长度,val就是字符串的值。这里的结构体定义的char val[1]是一种柔性数组的应用,这样我们可以直接打印出来这个值
str4.png
这就是php7中的字符串通过zval中的str指向到了zend_string结构体。

相关文章

  • php7中的zval结构体

    php7中的zval结构体对比php5优化了很多,一个zval只占用16字节的空间,php7中的zval的结构体如...

  • php7的zval相关介绍

    在php7中变量主要由zval保存,只占用16个字节zval结构如下 zval主要由value u1 和u2保...

  • PHP的面试总结

    PHP的垃圾回收机制是什么? php5和php7的垃圾回收机制都是利用引用计数。 在zval结构体中定义了ref_...

  • 【PHP7源码学习】系列之zval实现

    上一篇讲解了【PHP7源码学习】源码整体结构分析,从本篇开始讲解PHP7中第一个非常重要的结构 zval。 基础知...

  • PHP7变量的内部实现

    PHP5中的zval PHP5中zval结构体的定义如下: 可以看到,zval由value、type和一些额外的_...

  • PHP5变量的实现

    概述 PHP 中变量的值存储在 zval 结构体中,变量名存在符号表(symbol table)中,符号表的实际是...

  • PHP7 为什么变快了?

    PHP7比PHP5在性能上有很大的提升那么PHP7做了那些优化?变量存储优化 1.存储变量的结构体变小,结构体成员...

  • php7 zval及变量存储方式

    Zval是PHP中最重要的数据结构之一,它包含了PHP中变量的值和类型相关信息。 1. zval 1.1 zval...

  • PHP5垃圾回收机制

    在了解垃圾回收机制之前我们必须先来看下zval结构。zval是用于保存变量以及常量的。 php5中的zval数据结...

  • php7引用计数

    1. 什么是引用计数 在《php7 zval及变量存储方式》的2.3节中我们说到,对于复杂类型的变量(string...

网友评论

    本文标题:php7中的zval结构体

    本文链接:https://www.haomeiwen.com/subject/ddnqvqtx.html