深入理解PHP变量
读了鸟叔几篇关于PHP变量的相关文章后,自己对PHP变量有了更深层次的了解。
1、符号表–作用域
首先PHP变量这种弱语言的实现是基于利用一种hash table的结构,不同作用域会有不同的符号表(hash table)。当你创建一个变量的时候,PHP会为这个变量分配一个zval,填入相应的变量值,然后将这个变量的名字,和指向这个zval的指针填入一个数组中。然后,当你获取这个变量的时候,PHP会通过查找这个数组,获得对应的zval。符号表包括了全局符号表(静态变量我觉得应该也会保存一份在此)和活动符号表。其中,全局符号表,保存了在顶层作用域(就是不在任何函数,对象内)的变量。每当调用一个函数(对象的方法)的时候,就会为这个函数创建一个活动符号表,所有在这个函数内定义的变量,都会保存在这个活动符号表中。
2、zval结构
关于zval这个结构的定义:
1 2 3 4 5 6 | typedef struct _zval_struct { zvalue_value value; zend_uint refcount; zend_uchar type; zend_uchar is_ref; } zval; |
实现弱语言的关键就在于zvalue_value是个联合体,下面我们来看这个结构体的各个成员。
1 2 3 4 5 6 7 8 9 10 | typedef union _zvalue_value { long lval; double dval; struct { char *val; int len; } str; HashTable *ht; zend_object_value obj; } zvalue_value; |
PHP常见的变量类型包括整型、浮点型、长整形、bool、字符串、数组、对象、资源,当PHP变量取对应值时,type元素会赋为相对应的值,同时,zvalue_value会取对应的值类型。
关于is_ref,refcount这两个元素值的使用则涉及到PHP的COW策略,is_ref为引用,refcount为引用计数。关于这两个属性值PHP中可以利用xdebug中的xdebug_debug_zval()打印出变量的引用与计数值,不懂的请自行百度这个函数,顺便吐槽下PHP自带的debug_zval_dump()用来查看ref_count真的很不行,推荐xdebug_debug_zval()。实例:
1 2 3 4 5 6 7 | $test = array( 'a'=>1, 'b'=>2, 'c'=>3 ); xdebug_debug_zval('a'); |
文章参考: