诺亚方舟

沉淀

深入理解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');

 

文章参考:

深入理解PHP原理之变量分离/引用

深入理解PHP原理之变量

深入理解PHP原理之变量作用域

 

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>