php底层变量存储

变量存储

php的变量使用一个结构体 zval来保存的,在Zend/zend.h中我们可以看到zval的定义

struct _zval_struct {
    /* Variable information */
    zvalue_value value;          /* 变量的值 */
    zend_uint refcount__gc;            /* 变量被指向次数,指向一次+1 */
    zend_uchar type;            /* 变量当前的数据类型 */
    zend_uchar is_ref__gc;            /* 涉及到垃圾回收,以后补充 */
};

 

变量类型
1、整型/浮点/长整型/bool值
2、字符串
3、数组/关联数组
4、对象
5、资源

typedef union _zvalue_value {
    long lval;    /* long value */
    double dval;    /* double value */
    struct {    /*字符串*/
        char *val;    /**/
        int len;    /*字符串长度,因为这里存储字符串长度,所以在使用    strlen函数求长度是直接返回,效率非常快*/
    } str;
    HashTable *ht;    /* hash table value PHP数组底层其实是一个hashtable */
    zend_object_value obj;    /*对象*/
    zend_ast *ast;
} zvalue_value;

 

底层代码变量类型定义

/* data types */
/* All data types <= IS_BOOL have their constructor/destructors skipped */
#define IS_NULL    0
#define IS_LONG    1
#define IS_DOUBLE    2
#define IS_BOOL    3
#define IS_ARRAY    4
#define IS_OBJECT    5
#define IS_STRING    6
#define IS_RESOURCE    7
#define IS_CONSTANT    8
#define IS_CONSTANT_AST    9
#define IS_CALLABLE    10

#define IS_CONSTANT_TYPE_MASK    0x00f
#define IS_CONSTANT_UNQUALIFIED    0x010
#define IS_LEXICAL_VAR    0x020
#define IS_LEXICAL_REF    0x040
#define IS_CONSTANT_IN_NAMESPACE    0x100

#define IS_CONSTANT_TYPE(type) (((type) & IS_CONSTANT_TYPE_MASK) >= IS_CONSTANT && ((type) & IS_CONSTANT_TYPE_MASK) <= IS_CONSTANT_AST)

 

当我们在php代码中写$a = 3;
内存存储方式为:

 

使用xdebug_debug_zval('a');查看赋值时底层的变化
运行结果为:a: (refcount=1,is_ref=0)=3

当再赋值$b = $a;时
使用xdebug_debug_zval('a');
使用xdebug_debug_zval('b');
运行结果为:a: (refcount=2,is_ref=0)=3
      b: (refcount=2,is_ref=0)=3

 

当再给$b赋值,$b = 5;,这个时候用到了php的特性,写时复制(Copy On Write,简称COW,因为两者有一方修改值的时候,才会进行分裂),会赋值出来一份,不使用同一个内存块。
使用xdebug_debug_zval('a');
使用xdebug_debug_zval('b');
运行结果为:
a: (refcount=1,is_ref=0)=3
b: (refcount=1,is_ref=0)=5

 

posted @ 2019-08-02 16:54  独孤靖云  阅读(746)  评论(0编辑  收藏  举报