PHP中的变量作用域

变量的作用域,也叫变量的范围,即它定义的上下文背景,也是它的生效范围

局部变量和全局变量
PHP的变量作用域和全局变量 - 图1

1 函数作用域:

实例1:函数外部变量和函数内部完全隔绝,无法相互访问。

  1. <?php
  2. $test = 'hello,world';
  3. function abc(){
  4. echo($test);
  5. }
  6. abc(); //这里什么都不输出,因为访问不到$test变量


实例2:函数内部对外部传入的参数的修改,不影响外部函数的值。
除非函数的参数是引用的变量,对象,global等全局变量。且函数被执行之后,才会影响外部变量的值

  1. <?php
  2. $test = 'hello,world';
  3. function abc($test){
  4. $test = 'hi';
  5. echo($test);
  6. }
  7. echo '<pre>';
  8. print_r($test);//hello,world
  9. echo '</pre>';
  10. abc($test); // hi;
  11. echo '<pre>';
  12. print_r($test); //hello,world,内部对$test的修改不影响外部$test的值
  13. echo '</pre>';
  14. //如果function abc(&$test),那么第一个值还是hello,world,因为没有执行函数;第二个值是hi,第三个值就变成hi了,因为参数是引用的,会改变外部的变量值。


mysql事务中也是局部变量,需要使用use将外部变量带入。事务中对变量进行修改,不影响外部变量的值。除非是:
&引用的变量(共享一个内存的存储区域)
传入的是对象(在一个对象的方法中,$this 永远是调用它的对象的引用。
global申明的变量等全局变量(用 global $var 声明一个变量时实际上建立了一个到全局变量的引用

2 没有块级作用域,条件语句和循环中的变量对外部可见,而且内外部可以相互改变。PHP没有C/C++、java等语言的块级作用域概念

  1. if(3>2){
  2. $v = 10;
  3. }
  4. print_r($v); //输出10

如果不想让块级作用域中的变量影响到外部,可在外部初始化变量:$v = 0;
如果块级作用域中有引用该变量,且外部想重新使用这个变量。需要先unset这个变量, 最好是重新起个变量名。

  1. $arr = [1, 2, 4];
  2. foreach ($arr as &$val) {
  3. $val *= 2;
  4. }
  5. unset($val);
  6. $val += 1;//1,如不不unset该变量,值是9

3 超级全局变量

$_GET $_POST等内嵌超级全局变量无论在函数内还是函数外都是可见的。共有9大超全局变量

4 global和$GLOBALS[]

在全局范围内访问变量的第1个办法
我们可以使用global关键字来声明变量,上面的例子就变成了这样

  1. <?php
  2. $test = 'hello,world';
  3. abc();
  4. function abc(){
  5. global $test;
  6. echo $test;
  7. }

在全局范围内访问变量的第二个办法
用特殊的 PHP 自定义 $GLOBALS 数组。前面的例子可以写成:

  1. <?php
  2. $test = 'hello,world';
  3. function abc(){
  4. echo $GLOBALS['test'];
  5. }
  6. abc();

global和$GLOBALS区别

  1. <?php
  2. function test1() {
  3. global $v1, $v2;
  4. $v2 = &$v1;
  5. }
  6. function test2() {
  7. $GLOBALS['v4'] = &$GLOBALS['v3'];
  8. }
  9. $v1 = 1;
  10. $v2 = 2;
  11. $v3 = 1;
  12. $v4 = 2;
  13. test1();
  14. echo $v2 ; //2,不应该是1吗?
  15. test2();
  16. echo $v4; //1
  1. <?php
  2. function test1() {
  3. global $v1, $v2;
  4. $v2 = 9;
  5. }
  6. function test2() {
  7. $GLOBALS['v4'] =9;
  8. }
  9. $v2 = 2;
  10. $v4 = 2;
  11. test1();
  12. echo $v2 ; //9,这个咋又是9了,
  13. test2();
  14. echo $v4; //9


我们在看一个例子

  1. <?php
  2. function test() {
  3. global $a;
  4. unset($a);
  5. }
  6. $a = 1;
  7. test();
  8. echo $a; //1:global申明的变量并不是真正的函数外部变量。
  9. function test() {
  10. unset($GLOBALS['a']);
  11. }
  12. $a = 1;
  13. test();
  14. echo $a; // Undefined variable: a 函数内unset掉的确实是外部变量

总结:
global在函数内声明的变量,其实是外部变量的别名,
$GLOBALS[]是真正的调用外部的变量,函数内外始终保持一致。
global不算是真正的调用函数外部变量,当对global变量进行引用赋值的时候,会给global的变量重新生成一个内存地址,不影响外部的同名变量的值;当对global变量进行普通赋值,会改变外部变量的值。