我前面的文章(深刻理解PHP原理之变量(Variables inside PHP))介绍了PHP变量的内部表示,可是,问题是,这些内部表示是如何和用户脚本中的变量联系起来的呢?也就是说,若是我在脚本中写下:php
ZE是如何把个人变量var和内部结构zval联系起来的呢?html
深刻理解PHP原理之变量中讲过,PHP内部都是使用zval来表示变量的,可是对于上面的脚本,咱们的变量是有名字的, var。而zval中并无相应的字段来体现变量名。
若是你想到了PHP内部必定有一个机制,来实现变量名到zval的映射。那么你真的是很聪明,;)数组
在PHP中,全部的变量都会存储在一个数组中(确切的说是hash table), 而且,PHP也是经过不一样的数组来实现变量的做用域的。ide
当你建立一个变量的时候,PHP会为这个变量分配一个zval,填入相应的变量值,而后将这个变量的名字,和指向这个zval的指针填入一个数组中。而后,当你获取这个变量的时候,PHP会经过查找这个数组,得到对应的zval。函数
查看_zend_executor_globals结构(这个结构在PHP的执行器保存一些执行相关的上下文信息)spa
其中,全局符号表,保存了在顶层做用域(就是不在任何函数,对象内)的变量。每当调用一个函数(对象的方法)的时候,就会为这个函数建立一个活动符号表,全部在这个函数内定义的变量,都会保存在这个活动符号表中。指针
对,这就是PHP的变量做用域的实现方式! 举个列子:htm
在函数sample外面的变量$var,它会被填入全局符号表中,与他对应的有一个zval指针,这个zval保存了一个字符串”I am in the global symbol table”.
函数内的$var, 它会被填入属于函数sample的活动符号表中,同样的,与他对应的zval中,保存着字符串”I am in the active symbol table
“.
比较特殊的,就是函数sample的参数$para了,这个$para是保存在sample的活动符号表的,可是与他对应的zval指针,会指向一个保存一份全局变量$var的copy的zval(严格来说不是copy,是引用,这个涉及到变量的copy on write机制,我会在之后介绍)。对象
咱们都知道PHP对于简单变量是传值调用的,可是,我要告诉你的是,PHP并非简单的经过复制一个zval来实现传值的,呵呵,留个悬念,等我下回分解.作用域