PHP7变量的内部实现(一)

PHP7变量的内部实现-part 1

本文翻译自Nikita的文章,水平有限,如有错误,欢迎指正查看原文

受篇幅限制,这篇文章将分为两个部分。本部分会讲解PHP5和PHP7在zval结构体的差异,同时也会讨论引用的实现。第二部分会深入探究一些数据类型如string和对象的实现。

PHP5中的zval

PHP5中zval结构体的定义如下:

typedef struct _zval_struct {
    zvalue_value value;
    zend_uint refcount__gc;
    zend_uchar type;
    zend_uchar is_ref__gc;
} zval;

可以看到,zval由value、type和一些额外的__gc信息组成。__gc与垃圾回收相关,我们稍后讨论。value是一个共用体,可以存储y一个zval各种可能的值。

typedef union _zvalue_value {
    long lval;                 // For booleans, integers and resources
    double dval;               // For floating point numbers
    struct {                   // For strings
        char *val;
        int len;
    } str;
    HashTable *ht;             // For arrays
    zend_object_value obj;     // For objects
    zend_ast *ast;             // For constant expressions
} zvalue_value;

C语言中,共用体的尺寸与它最大的成员尺寸相同,在某一时刻只能有一个成员处于活动状态。共用体所有的成员都存储在相同的内存,根据你访问的成员不同,内容会被解释成不同的类型。以上面的共用体为例,如果访问lval,值将被解释为一个有符号整型;而访问dval将被解释成双精度浮点型。以此类推。

为了弄清结构体中哪个成员处于活动状态,zval会存储一个整型type来标识具体的数据类型。

#define IS_NULL     0      /* Doesn't use value */
#define IS_LONG     1      /* Uses lval */
#define IS_DOUBLE   2      /* Uses dval */
#define IS_BOOL     3      /* Uses lval with values 0 and 1 */
#define IS_ARRAY    4      /* Uses ht */
#define IS_OBJECT   5      /* Uses obj */
#define IS_STRING   6      /* Uses str */
#define IS_RESOURCE 7      /* Uses lval, which is the resource ID */

/* Special types used for late-binding of constants */
#define IS_CONSTANT 8
#define IS_CONSTANT_AST 9

相关推荐