最近在读php7内核,本文是由《PHP7内核剖析》整理而来。
静态变量
PHP中局部变量分配在zend_execute_data结构上,每次执行zend_op_array都会生成一个新的zend_execute_data,局部变量在执行之初分配,然后在执行结束时释放,这是局部变量的生命周期,而局部变量中有一种特殊的类型:静态变量,它们不会在函数执行完后释放,当程序执行离开函数域时静态变量的值被保留下来,下次执行时仍然可以使用之前的值。
PHP中的静态变量通过static关键词创建:
function my_func(){
static $count = 4;
$count++;
echo $count,"\n";
}
my_func();
my_func();
===========================
5
6
静态变量的存储
静态变量既然不会随执行的结束而释放,那么很容易想到它的保存位置:zend_op_array->static_variables,这是一个哈希表,所以PHP中的静态变量与普通局部变量不同,它们没有分配在执行空间zend_execute_data上,而是以哈希表的形式保存在zend_op_array中。
静态变量只会初始化一次,注意:它的初始化发生在编译阶段而不是执行阶段,上面这个例子中:static $count = 4;是在编译阶段发现定义了一个静态变量,然后插进了zend_op_array->static_variables中,并不是执行的时候把static_variables中的值修改为4,所以上面执行的时候会输出5、6,再次执行并没有重置静态变量的值。
这个特性也意味着静态变量初始的值不能是变量,比如:static $count = $xxx;这样定义将会报错。
静态变量的访问
局部变量通过编译时确定的编号进行读写操作,而静态变量通过哈希表保存,这就使得其不能像普通变量那样有一个固定的编号,有一种可能是通过变量名索引的,那么究竟是否如此呢?我们分析下其编译过程。
静态变量编译的语法规则:静态变量编译的语法规则:
statement:
...
| T_STATIC static_var_list ';' { $$ = $2; }
...
;
static_var_list:
static_var_list ',' static_var { $$ = zend_ast_list_add($1, $3); }
| stati