你可能已经注意到了,当在包含文件中使用变量的时候,只需要在脚本中的require和include语句前声明它们,但是在使用函数的时候,则要明确地将这些变量传递给函数。一方面是因为没有将变量传给所需或包含文件的机制,另一方面是因为变量的作用域相对于函数是不同的。
变量的作用域可以控制变量在哪里是可见并且可用的。不同的编程语言有不同的变量作用域规则。PHP具有相当简单的规则:
■在函数内部声明的变量作用域是从声明它们的那条语句开始到函数末尾。这叫做函数作用域。这些变量称为局部变量。
■在函数外部声明的变量作用域是从声明它们的那条语句开始到文件末尾,而不是函数内部。这叫做全局作用域。这些变量称为全局变量。
■特殊的超级全局变量在函数内部和外部都是可见的。(请参阅第1章,“PHP快速入门教程”获得这些超级全局变量的更多信息。)
■使用require和include并不影响作用域。如果这两个语句用于函数内部,函数作用域适用。如果它不在函数内部,全局作用域适用。
■关键字"global"可以用来手动指定一个在函数中定义或使用的变量具有全局作用域。
■通过调用unset($variable_name)可以手动删除变量。如果变量被删除,它就不在参数所指定的作用域中了。
下面的例子可能有助于我们更好地理解这些规则。
下面的代码没有输出。在这里,我们在函数fn内部声明了一个名为$var的变量。因为这个变量是在函数内部声明的,所以它具有函数作用域并只在它所声明的地方存在,直到函数末尾。当在函数外部再次引用变量$var的时候,一个新的$var变量就会被创建。
这个新的变量具有全局作用域,在到达文件末尾之前都是可见的。不幸的是,如果唯一使用该变量的命令是echo,它将不会被赋值。
function fn{
$var="contents";
}
fn;
echo$var;
如下所示的例子刚好相反。我们在函数外部声明一个变量,然后在函数内部使用它:
<?
function fn{
echo"inside the function,/$var=".$var."<br/>";
$var="contents 2";
echo"inside the function,/$var=".$var."<br/>";
}
$var="contents 1";
fn;
echo"outside the function,/$var=".$var."<br/>";
这段代码的输出如下所示:
inside the function,$var=
inside the function,$var=contents 2
outside the function,$var=contents 1
函数在被调用之前是不会执行的,所以第一条执行的语句是$var='contents 1'。该语句创建了一个名为$var的变量,它具有全局作用域且值为"contents 1"。下一条执行的语句是调用函数fn。函数内部的代码按顺序执行。函数第一行引用了一个名为$var的变量。当这行被执行时,就不能看到前面创建的变量$var了,所以它创建了一个具有函数作用域的新变量并将它显示出来。这就是输出的第一行。
函数内的下一行代码将变量$var的内容设为"contents 2"。因为是在函数内部,所以这一行改变了局部变量$var值,而不是那个全局变量。输出的第二行证实了这个改变。
函数执行到这里就结束了,这时脚本的最后一行被执行。这个echo命令显示了全局变量的值没有改变。
如果希望一个在函数内部创建的变量具有全局域,可以按如下方式使用关键字"global":
function fn{
global$var;
$var="contents";
echo"inside the function,/$var=".$var."<br/>";
}
fn;
echo"outside the function,/$var=".$var."<br/>";
在这个例子中,变量$var被明确地声明为全局变量,这就意味着在函数调用结束之后,变量在函数外部也存在。这个脚本的输出如下所示:
inside the function,$var=contents
outside the function,$var=contents
请注意,变量的作用域是从执行global$var;这一行语句开始的。函数的声明可以在调用它之前或之后(请注意,函数的作用域不同于变量的作用域!),因此在哪里声明函数并不重要,重要的是在哪里调用并执行其中的代码。
当一个变量要在整个脚本中都要用到时,也可以在脚本的开始处使用关键字"global"。
这可能是使用关键字global更常见的办法。
在前面的例子中,可以看到在函数的内部和外部重复命名一个变量名是合法的,而且两者互不影响。但是一般来说,这并不是一个好办法,因为如果不认真阅读代码并考虑作用域,人们可能会认为这些变量都是同一个。