3.2.1 PHP5的zval
    image.png
    PHP5的zval核心由一个zvalue_value的联合体和zend_uchar类型的type组成。在PHP5.3之后相继引入了refcount_gc字段通过引用计数进行垃圾回收,同时增加了新的字段is_ref_gc来标记是否为引用类型。

    image.png
    zval结构体24字节
    union u联合体8字节 (解决循环引用问题)
    zend_mm_block结构体16字节 (开启zend内存池情况下)
    所以一个变量在PHP5中实际占用的内存大小为48字节

    3.2.2 PHP7的zval
    image.png
    PHP7的zval保留了value字段,value支持更丰富的类型。且zval不再存储复杂类型的结构,复杂类型的数据都是通过指针操作的,新的联合体中value内存只占用8个字节。
    zval中还有两个重要字段u1和u2,都是联合体结构。
    u1中字段含义
    type:记录变量类型
    type_flag:对应变量特有的标记
    const_flag:常量类型的标记
    reserved:保留字段
    u2中字段含义
    next:解决哈希冲突问题
    cache_slot:运行时缓存
    lineno:文件执行的行号,应用在AST节点上
    num_argus:函数调用时,传入参数的个数
    fe_pos:遍历数组时的当前位置
    fe_iter_idx:遍历对象的属性
    access_flags:对象类的访问标志,常用的有pulic,protected,private
    property_guard:防止类中魔术方法的循环调用,比如get,set等
    image.png
    PHP5时代,所有的变量都在堆中申请,但是对于临时变量是没有必要的。
    PHP7临时变量直接在类中申请。

    3.2.3 PHP7变量类型
    image.png
    PHP7中定义了20种宏,用来标记u1.v.type字段,根据不同的type值取value对应的不同值。
    新增的类型:
    IS_UNDEF:标记未定义,表示数据可以被覆盖或删除
    IS_TRUE 和 IS_FALSE:这里将 IS_BOOL 优化成两个,直接将布尔类型的标记记录在 type 中,这样做可以优化类型的检查,不需要再做一次类型判断。
    IS_REFERENCE:处理引用「&」
    IS_INDIRECT
    iS_PTR:该类型被定义为指针类型
    _IS_ERROR:检查zval的类型是否合法

    3.2.4 整型和浮点型
    image.png
    3.2.5 字符串类型
    image.png
    PHP7中的字符串是通过zval.value.str指向zend_string结构体的
    image.png
    3.2.6 数组
    PHP的数组是有序的字典,即它们表示key-value对的有序列表,其中key-value映射是使用HashTable实现的。
    3.2.7 传引用
    正常赋值
    image.png
    image.png
    3.2.7 引用
    当使用「&」时,会创建一种新的中间结构体zend_reference,这个结构体会指向真正的zend_string结构体
    3.2.8 间接zval
    image.png
    PHP代码通过词法和语法解析成AST树,zend引擎根据AST树生成opcodes数组,zend引擎模拟了一个执行栈来逐条执行opcodes数组中的opcode。
    在编译时已知所有变量都被赋予一个索引,并且将他们的值将存储在编译变量(cv)表中。
    PHP允许使用变量来动态的引用变量,或者如果在全局范围内,则使用$GLOBALS。
    如果发生这样的访问,PHP将为函数/脚本创建一个符号表,其中包含从变量名到其值的映射。
    3.2.9 常量和常量AST
    常量就是指固定值,在执行期间不会改变,这些固定的值也叫做字面量。
    PHP 底层在做词法和语法解析时会将字面量解析,并将其类型修改为 IS_CONST。
    3.2.10 资源类型
    image.png