在每种语言中,变量定义后都有一个作用域,当然PHP中,变量也都有一个作用域,今天要学习的就是PHP的变量作用域。
一个变量的作用域就是变量定义的上下文。在大多数情况下,所有的PHP变量只有一个作用域。这个唯一的作用域将会应用到包含文件(included files和required files)中去,比如说下面的例子:
var_scope1.php的代码
1234
var_scope1_inc.php的代码
12
脚本var_scope1.php的执行结果如下:
1
1
可以看到$a在inc文件中也是有效的。
而在函数中,一个本地作用域将被导入,任何在函数内部使用的变量的作用域都被限制在这个函数的本地作用域,例如:
var_scope1.php的代码
1234567891011
var_scope1_inc.php的代码
123456
脚本var_scope1.php的执行结果如下:
123
inside global scope: a=1inside function testFunc: a=inside function testFuncP: a=
结果里,testFunc与testFuncP中的a的值都为空,因为这个时候打印$a变量的值时打印的函数本地域的值,但是函数中没有定义$a变量,因此打印出来都为空值。这个与C里面的全局变量不太一样,在C中,在函数内部如果没有定义与全局变量同名的局部变量,那么在函数中全局变量将被使用。
那么,在函数内部就不能访问到全局变量了么,还是有办法的,有两种办法。
方法一,使用global关键字,在函数内部,利用global关键字声明一下要使用的全局变量。比如下例:
var_scope2.php的代码
123456789101112131415161718
脚本执行的结果如下:
123
Inside noGlobalFunc: a=, b=Inside useGlobalFunc: a=1, b=2Result: a=1, b=3
另外,在函数之外使用global关键字不会出错。如下例:
global_keyword_inc.php的代码
1234
global_keyword.php的代码
1234567891011
$a = 1;$b = 2; function incGlbalFunc() { include_once 'global_keyword_inc.php';} incGlbalFunc(); echo "Result: a=$a, b=$b";
脚本global_keyword.php的执行的结果如下:
1
Result: a=1, b=3
上例中,global_keyword.php中incGlobalFunc函数包含了global_keyword_inc.php,在后者中变量$a和$b的声明使用了global关键字。
对引用类型的变量使用global关键字时,需要注意在函数中global语句实际上是只是创建了一个指向全局变量的引用,如果在函数中修改的只是引用指向,那么就能反映到全局变量中,如果将变量的引用修改了,那么就不会反映到全局变量。比如说下例:
global_keyword.php的代码
123456789101112131415
脚本执行的结果如下:
123
NULLobject(stdClass)#1 (0) {}
test_global_ref中,将$obj的引用改变了,根据我的另外一篇博客 PHP研究之引用计数器(Reference Counting)的说明,此时$obj指向了另外一个ZVal容器了,与刚开始的全局变量指向的不是一个Zval容器,因此,返回的结果是NULL,而第二个因为函数的$obj与全局变量$obj指向指向的是同一个Zval容器,在函数内更改的只是ZVal的值,因此函数的更改反映到了全局变量中。
方法二,利用PHP中的$GLOBALS数组。
例:
12345678910
上面脚本的执行结果如下:
12
$foo in global scope: Example content$foo in current scope: local variable