一、静态变量:
特点:静态变量函数返回调用之时并不会释放,它的结果会被保留到下次函数的调用,其生命周期比局部变量长;
静态变量可以分为:
- 静态全局变量,PHP中的全局变量也可以理解为静态全局变量,因为除非明确unset释放,在程序运行过程中始终存在。
- 静态局部变量,也就是在函数内定义的静态变量,函数在执行时对变量的操作会保持到下一次函数被调用。
- 静态成员变量,这是在类中定义的静态变量,和实例变量相对应,静态成员变量可以在所有实例中共享。
底层逻辑:静态变量不会像普通变量一样分配在zend_execute_data上,而是保存在zend_op_array->sratic_variables中,这是一个哈希结构。静态变量只会初始化一次,而且他的初始化是发生在编译阶段不是执行阶段;下面例子
function my_func(){
statis $count = 5;
$count++;
echo $count;
}
my_func();
my_func();
最后输出:6,7
上面的例子,在编译阶段就发现定义一个静态变量,然后存入zend_op_array->sratic_variables,在编译的时候不会重新定义,没有重置值,因为普通变量是在执行阶段定义,所以静态变量的初始值不能是变量;
二、常量
特点:在脚本执行期间不能改变
常量存储在EG哈希表中,访问是也是根据常量名直接到哈希表中查找,
define和const的其它区别:
1.const不能再条件语句中定义常量,但是define是可以的
2.const采用一个普通的常量名称,define可以采用表达式作为名称
3.const只能接受静态的标量,而define可以采用任何表达式。
4.const本身就是一个语言结构。而define是一个函数。所以使用const速度要快的多。
三、全局变量
特点:定义在函数、类之外的变量成为全局变量;
全局变量的值都保存在全局符号表中,全局变量并不是通过单独的指令注册到EG符号表,而是在执行前,有内核自动将主代码中的局部变量导入全局变量符号表,即使代码里没有使用全局变量的地方也会导入到该符号表,倒导入的过程在zend_execete_ec()执行之前完成的。全局变量的访问是将全局变量转换为引用类型,然后将局部变量指向这个引用,
执行步骤:zend_attach_symbol_table()将局部变量导入全局符号表,将变量存在局部变量名的zend_op_array->vars数组,然后以变量名为key插入EG,value指向zend_execute_data上对应的局部变量。