PHP中的变量作用域
变量的作用域,也叫变量的范围,即它定义的上下文背景,也是它的生效范围
局部变量和全局变量
1 函数作用域:
实例1:函数外部变量和函数内部完全隔绝,无法相互访问。
<?php
$test = 'hello,world';
function abc(){
echo($test);
}
abc(); //这里什么都不输出,因为访问不到$test变量
实例2:函数内部对外部传入的参数的修改,不影响外部函数的值。
除非函数的参数是引用的变量,对象,global等全局变量。且函数被执行之后,才会影响外部变量的值
<?php
$test = 'hello,world';
function abc($test){
$test = 'hi';
echo($test);
}
echo '<pre>';
print_r($test);//hello,world
echo '</pre>';
abc($test); // hi;
echo '<pre>';
print_r($test); //hello,world,内部对$test的修改不影响外部$test的值
echo '</pre>';
//如果function abc(&$test),那么第一个值还是hello,world,因为没有执行函数;第二个值是hi,第三个值就变成hi了,因为参数是引用的,会改变外部的变量值。
mysql事务中也是局部变量,需要使用use将外部变量带入。事务中对变量进行修改,不影响外部变量的值。除非是:
&引用的变量(共享一个内存的存储区域)
传入的是对象(在一个对象的方法中,$this 永远是调用它的对象的引用。)
global申明的变量等全局变量(用 global $var 声明一个变量时实际上建立了一个到全局变量的引用)
2 没有块级作用域,条件语句和循环中的变量对外部可见,而且内外部可以相互改变。PHP没有C/C++、java等语言的块级作用域概念
if(3>2){
$v = 10;
}
print_r($v); //输出10
如果不想让块级作用域中的变量影响到外部,可在外部初始化变量:$v = 0;
如果块级作用域中有引用该变量,且外部想重新使用这个变量。需要先unset这个变量, 最好是重新起个变量名。
$arr = [1, 2, 4];
foreach ($arr as &$val) {
$val *= 2;
}
unset($val);
$val += 1;//1,如不不unset该变量,值是9
3 超级全局变量
$_GET $_POST等内嵌超级全局变量无论在函数内还是函数外都是可见的。共有9大超全局变量
4 global和$GLOBALS[]
在全局范围内访问变量的第1个办法
我们可以使用global关键字来声明变量,上面的例子就变成了这样
<?php
$test = 'hello,world';
abc();
function abc(){
global $test;
echo $test;
}
在全局范围内访问变量的第二个办法
用特殊的 PHP 自定义 $GLOBALS 数组。前面的例子可以写成:
<?php
$test = 'hello,world';
function abc(){
echo $GLOBALS['test'];
}
abc();
global和$GLOBALS区别
<?php
function test1() {
global $v1, $v2;
$v2 = &$v1;
}
function test2() {
$GLOBALS['v4'] = &$GLOBALS['v3'];
}
$v1 = 1;
$v2 = 2;
$v3 = 1;
$v4 = 2;
test1();
echo $v2 ; //2,不应该是1吗?
test2();
echo $v4; //1
<?php
function test1() {
global $v1, $v2;
$v2 = 9;
}
function test2() {
$GLOBALS['v4'] =9;
}
$v2 = 2;
$v4 = 2;
test1();
echo $v2 ; //9,这个咋又是9了,
test2();
echo $v4; //9
我们在看一个例子
<?php
function test() {
global $a;
unset($a);
}
$a = 1;
test();
echo $a; //1:global申明的变量并不是真正的函数外部变量。
function test() {
unset($GLOBALS['a']);
}
$a = 1;
test();
echo $a; // Undefined variable: a 函数内unset掉的确实是外部变量
总结:
global在函数内声明的变量,其实是外部变量的别名,
$GLOBALS[]是真正的调用外部的变量,函数内外始终保持一致。
global不算是真正的调用函数外部变量,当对global变量进行引用赋值的时候,会给global的变量重新生成一个内存地址,不影响外部的同名变量的值;当对global变量进行普通赋值,会改变外部变量的值。