PHP变量的作用范围
天下维客,你可以修改的网络知识库
| PHP变量简明教程 | PHP变量的作用范围 | PHP变量的声明 | PHP的预定义变量 | PHP变量函数 | PHP的外部变量 |
| PHP的可变变量 |
变量的作用范围即它所起作用的范围(或称作用域)。
- 局部变量:多数PHP变量都是局部变量,在其作用域外无法引用,并且超出其作用域时自动销毁。
- 作用域:
- 1、在当前文件主程序中定义的变量,其作用域限于当前文件的主程序,不能在其他文件或当前文件的局部函数中起作用。
- 2、在局部函数中定义的变量仅限于当前函数,当前文件中主程序、其他函数、其他文件中无法引用。
- 全局变量:特殊指定的变量,可以在更大范围内进行使用。
- 作用域:在函数中使用全局变量时,可以与当前文件的主体程序中公用变量。
- 静态变量:特殊制定的变量,超出范围后不销毁,再次使用时保持前值。
- 作用域:当前文件的当前函数。
注:以上的作用域说明中,当前文件范文包括 include / require 所引入的语句。例如:
<?php $a = 1; include 'b.inc'; // $a将会在 b.inc 中继续生效。 function Test() { echo $a; // 局部函数中的局部变量,与主程序的$a并非同一变量。 // 因此本句将会出现变量未定义的警告,而无其他输出。 } Test(); ?>
对于类(Class)中定义的变量,其作用域说明参见{{{1}}}(欢迎补充资料)
PHP的全局变量
PHP的全局变量和C语言稍有不同:C语言中,全局变量在函数中自动生效,除非被局部变量覆盖。这可能引起一些问题,有些人可能漫不经心的改变一个全局变量。
而在 PHP 中,在函数中使用全局变量时必须使用“global”关键字申明为全局,否则视为局部变量。 全局变量的个数没有限制
global 关键字 首先,一个使用 global 的例子:
在全局范围内访问变量的第二个办法,是用特殊的 PHP 自定义 $GLOBALS 数组。前面的例子可以写成:
例子 12-2. 使用 global
在 $GLOBALS 数组中,每一个变量为一个元素,键名对应变量名,值对应变量的内容。$GLOBALS 之所以在全局范围内存在,是因为 $GLOBALS 是一个超全局变量。以下范例显示了超全局变量的用处:
例子 12-4. 演示超全局变量和作用域的例子
<?php function test_global() { // 大多数的预定义变量并不 "super",它们需要用 'global' 关键字来使它们在函数的本地区域中有效。 global $HTTP_POST_VARS; echo $HTTP_POST_VARS['name']; // Superglobals 在任何范围内都有效,它们并不需要 'global' 声明。Superglobals 是在 PHP 4.1.0 引入的。 echo $_POST['name']; } ?>
PHP的静态变量
变量范围的另一个重要特性是静态变量(static variable)。静态变量仅在局部函数域中存在,但当程序执行离开此作用域时,其值并不丢失。看看下面的例子:
<?php function Test() { static $a = 0; //静态变量,仅首次调用时赋初值。不使用static的话,则每次都会赋值 echo $a; $a++; //每次调用时,在前次$a基础上加一 } ?>
静态变量也提供了一种处理递归函数的方法。递归函数是一种调用自己的函数。写递归函数时要小心,因为可能会无穷递归下去。必须确保有充分的方法来中止递归。一下这个简单的函数递归计数到 10,使用静态变量 $count 来判断何时停止:
例子 12-7. 静态变量与递归函数
<?php function Test() { static $count = 0; $count++; echo $count; if ($count < 10) { Test(); } $count--; } ?>
注: 静态变量可以按照上面的例子声明。如果在声明中用表达式的结果对其赋值会导致解析错误。
例子 12-8. 声明静态变量
<?php function foo(){ static $int = 0; // 正确 static $int = 1+2; // 错误,不能用表达式为静态变量赋初值 static $int = sqrt(121); // 错误,同样使用了表达式 $int++; echo $int; } ?>
全局和静态变量的引用
在 Zend 引擎 1 代,它驱动了 PHP4, 对于变量的 static 和 global 定义是以references方式实现的(这个方法来源于第一代Zend引擎对PHP4的驱动)。例如,在函数域内部用 global 声明一个全局变量,实际上是在函数内部建立了一个对全局变量的同名引用。这有可能导致预料之外的行为,如以下例子所演示的:
<?php function test_global_ref() { global $obj; $obj = &new stdclass; } function test_global_noref() { global $obj; $obj = new stdclass; } test_global_ref(); var_dump($obj); //输出结果: NULL test_global_noref(); var_dump($obj); //输出结果: object(stdClass)(0) {} ?>
类似的行为也适用于 static 语句。引用并不是静态地存储的:
<?php function &get_instance_ref() { static $obj; echo 'Static object: '; var_dump($obj); if (!isset($obj)) { $obj = &new stdclass; // 将一个引用赋值给静态变量 } $obj->property++; return $obj; } function &get_instance_noref() { static $obj; echo 'Static object: '; var_dump($obj); if (!isset($obj)) { $obj = new stdclass; // 将一个对象赋值给静态变量 } $obj->property++; return $obj; } $obj1 = get_instance_ref(); $still_obj1 = get_instance_ref(); echo "\n"; $obj2 = get_instance_noref(); $still_obj2 = get_instance_noref(); ?>
执行以上例子会导致如下输出:
Static object: NULL Static object: NULL
Static object: NULL Static object: object(stdClass)(1) {
["property"]=> int(1)
}
上例演示了当把一个引用赋值给一个静态变量时,第二次调用 &get_instance_ref() 函数时其值并没有被记住。


