PHP变量作用域仅有全局、局部、静态、超全局四种,无块级作用域;global用于引入已存在全局变量,static变量首次初始化后保留值,超全局数组任意位置可直接访问。

PHP 变量作用域只有这四种:全局、局部、静态、超全局
PHP 里没有“块级作用域”(比如 if 或 for 里声明的变量不会被限制在括号内),作用域只跟函数、类、文件和特殊关键字有关。理解错这点,就容易以为 $x 在 if 里定义后外面用不到——其实它就在当前作用域里,该访问还是能访问。
-
global关键字不是声明新变量,而是把已存在的全局变量“拉进”函数内部使用;漏写global直接读取同名变量,得到的是局部未初始化值(null或警告) - 函数参数、
foreach的循环变量、list()解构出的变量,都属于函数局部作用域 -
static变量只在首次执行时初始化,之后函数重复调用会保留上次的值——但它仍属于函数局部作用域,外部不可见 - 超全局数组(如
$_GET、$_SESSION)在任何作用域都能直接读写,不需要global声明
为什么在函数里改不了全局变量的值
常见错误是这样写:
$count = 0;
function increment() {
$count++; // 这里操作的是局部变量 $count,和外面那个毫无关系
}
increment();
echo $count; // 输出还是 0
根本原因:PHP 默认函数内所有变量都是局部的,哪怕名字和全局变量一样,也是独立副本。
- 要修改全局变量,必须显式用
global $count;声明,或用$GLOBALS['count']++ -
global声明必须在函数体开头附近,不能放在条件分支里(否则语法错误) - 如果变量是引用传参(
&$v),那函数内对$v的修改会影响外部,但这是传参机制,不是作用域规则
require / include 引入的文件,变量作用域怎么算
被引入文件里的代码,直接“嵌入”到当前作用域执行。也就是说:include 'a.php' 后,a.php 里定义的 $x 就成了当前作用域的变量——无论当前是在全局还是某个函数里。
立即学习“PHP免费学习笔记(深入)”;
- 在函数里
include,那么a.php中的变量属于该函数的局部作用域 - 在全局作用域
include,变量就进入全局作用域 - 注意:如果
a.php里用了return $val;,include表达式会返回这个值,但其他变量照常注入当前作用域 - 别依赖这种机制做模块封装——可读性差,调试时变量来源难追踪
闭包(anonymous function)里的 use 是作用域的例外吗
不是例外,而是明确声明“我要带哪些外部变量进来”。use 不是自动捕获,不写就不带;而且默认是值传递,要引用得加 &。
-
function () use ($x) { ... }→ 带进来的$x是定义闭包时的快照值 -
function () use (&$x) { ... }→ 闭包内修改$x,会影响外部变量 -
use不能访问$this(除非加上use ($this),但 PHP 7.1+ 才允许) - 闭包本身仍是函数,它没有自己的“全局作用域”,
use是唯一能接触外部变量的方式
最容易被忽略的是:static 变量和 use 都会制造“状态残留”,但前者绑定函数,后者绑定闭包实例——同一个函数多次调用生成的不同闭包,use 的变量互不影响,而 static 是共享的。











