$a = 1;
include 'b.php';
这里变量 $a 将会在包含文件 b.inc 中生效。但是,在用户自定义函数中,一个局部函数范围将被引入。任何用于函数内部的变量按缺省情况将被限制在局部函数范围内。例如
$a = 1; /* global scope */
function Test()
{
echo $a; /* reference to local scope variable */
}
Test();
这个脚本不会有任何输出,因为 echo 语句引用了一个局部版本的变量 $a,而且在这个范围内,它并没有被赋值。**PHP 中全局变量在函数中使用时必须声明为 global。**
在函数体内定义的global变量,定义后可以全局使用使用,在函数体外定义的global变量不能在函数体内使用,具体看下面示例。
(1)在函数体内定义global变量,函数体内可以使用。
(2)在函数体外定义global变量,函数体内不可以使用。
global $a;
$a = 3;
function test() {
var_dump($a);
var_dump($GLOBALS);die;
}
test();
//结果
Notice: Undefined variable: a in /users/kano/home/ts/123.php on line 5
Call Stack
/users/kano/home/ts/123.php:5:null
/users/kano/home/ts/123.php:6:int 3
// 可以看到其实全局变量是没问题的,但是在函数内定义的$a并非全局变量里的$a.如果要在全局变量内访问到$a的值,可以通过$GLOBALS['a']来解决。
示例:先使用global定义
$a = 1;
$b = 2;
function Sum()
{
global $a, $b; //在里面声明为全局变量
$b = $a + $b;
}
Sum();
echo $b;
使用$GLOBALS定义全局变量
$a = 1;
$b = 2;
function Sum(){
$GLOBALS["b"] = $GLOBALS["a"] + $GLOBALS["b"];//定义变量时每个都要定义
}
Sum();
echo $b; //输出结果为2
以上两种写法等价。
function test_global()
{
global $var1, $var2;
//声明两个全局变量$GLOBALS['var1']和$GLOBALS['var2'],
//并且创建全局变量的引用
//$var1 $GLOBALS['var1'] 指向同一个内存地址A
//$var2 $GLOBALS['var2'] 指向同一个内存地址B
$var2 =& $var1;
//引用关系改变 $var2指向A,所以$var2=内存地址A的内容
//而$GLOBALS['var2']仍指向B
}
function test_globals()
{
$GLOBALS['var3'] =& $GLOBALS['var1'];
//全局变量var3和var1指向共同的内容,$var3=$var1
}
$var1 = 5;
$var2 = $var3 = 0;
test_global();
print $var2; //输出结果为0
test_globals();
print $var3; //输结果为05
global 引用 当用 global $var 声明一个变量时实际上建立了一个到全局变量的引用。也就是说和这样做是相同的:
$var =& $GLOBALS["var"];
这意味着,例如,unset $var 不会 unset 全局变量。
$this 在一个对象的方法中,$this 永远是调用它的对象的引用。
//下面再来个小插曲 php中对于地址的指向(类似指针)功能不是由用户自己来实现的,是由Zend核心实现的,php中引用采用的是“写时拷贝”的原理,就是除非发生写操作,指向同一个地址的变量或者对象是不会被拷贝的。
通俗的讲 1:如果有下面的代码
$a="ABC"; $b=$a;
其实此时 $a与$b都是指向同一内存地址 而并不是$a与$b占用不同的内存
2:如果在上面的代码基础上再加上如下代码
$a="EFG";
由于$a与$b所指向的内存的数据要重新写一次了,此时Zend核心会自动判断自动为$b生产一个$a的数据拷贝,重新申请一块内存进行存储
文章参考:php中引用&的真正理解-变量引用、函数引用、对象引用
PHP中的全局变量global和$GLOBALS的区别