PHP内核变量存储

PHP作为一门弱类型语言,其变量类型可任意改变。而C作为PHP的底层实现,是通过结构及联合来实现PHP变量的弱类型特性的。在PHP源码中,Zend/zend.h文件有关于PHP变量的结构定义。

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
typedef struct _zval_struct zval;
 
typedef union _zvalue_value {
    long lval;      /* long value */
    double dval;    /* double value */
    struct {
        char *val;
        int len;
    } str;
    HashTable *ht;  /* hash table value */
    zend_object_value obj;
} zvalue_value;
 
struct _zval_struct {
    /* Variable information */
    zvalue_value value;     /* value */
    zend_uint refcount__gc;
    zend_uchar type;        /* active type */
    zend_uchar is_ref__gc;
};

    PHP的变量值,存储于zvalue_value这个联合当中。从其定义可以看出PHP是如何实现单一变量支持不同类型的。lval实现整型及资源类型的存储,dval实现长整型或浮点型存储,str实现字符串的存储,ht是一个哈希表的指针,用于数组的实现,obj实现对象类型
    再看看zval这个结构,zval是实现PHP变量存储机制的核心。包含四个成员,value是变量值,type表示变量的类型,为unsigned char类型,其值在内核中有对应的常量定义,分别对应PHP的八种数据类型。这八个常量是:IS_NULL, IS_BOOL, IS_LONG, IS_DOUBLE, IS_STRING, IS_ARRAY, IS_OBJECT, IS_RESOURCE。可见,根据type和value两个成员,即可实现PHP当中的八种变量类型。假如有以下PHP代码:

1
2
3
4
$a = 4323;
echo $a;
$a = "hello world";
echo $a;

运行第一句的时候,变量$a对应的zval结构当中的type成员值设置为IS_LONG,取值打印的时候就取value中的lval成员。然后运行第三句,将一个字符串赋值给变量$a,此时对应的zval结构的type成员值就被设置成了IS_STRING,然后取值的时候就根据value中的str结构的字符指针去获取字符串。

原文地址:https://www.cnblogs.com/penciler/p/4234280.html