PHP变量作用域与生命周期指南理解变量的作用域和生命周期是写好PHP代码的基础。PHP的变量作用域规则跟C语言有些像但又有自己的特点。PHP有局部变量、全局变量、静态变量和超全局变量几种。每种的作用域和生命周期都不一样。php// 全局变量$globalVar 全局变量;function testScope(): void{// 局部变量$localVar 局部变量;echo $localVar . \n;// 在函数内访问全局变量需要用global关键字global $globalVar;echo $globalVar . \n;// 或者用$GLOBALS数组echo $GLOBALS[globalVar] . \n;// 静态变量static $count 0;$count;echo 调用次数: $count\n;}testScope();testScope();testScope();// echo $localVar; // 报错局部变量在函数外不可访问?静态变量的生命周期贯穿整个请求。在函数内用static声明的变量函数退出后不会销毁下次调用时上次的值还在。phpfunction fibonacciGenerator(): Closure{return function () {static $a 0;static $b 1;$current $a;$next $a $b;$a $b;$b $next;return $current;};}$fib fibonacciGenerator();for ($i 0; $i 10; $i) {echo $fib() . ;}echo \n;?变量引用用符号多个变量可以指向同一个值。php// 引用赋值$a 10;$b $a; // $b引用$a$b 20; // 修改$b$a也变了echo a: $a, b: $b\n; // a: 20, b: 20// 引用传参function addItem(array $arr, mixed $item): void{$arr[] $item; // 直接修改原数组}$list [1, 2, 3];addItem($list, 4);print_r($list); // [1, 2, 3, 4]// 引用返回class Singleton{private static array $instances [];public static function get(string $key): mixed{if (!isset(self::$instances[$key])) {self::$instances[$key] [];}return self::$instances[$key]; // 返回引用}}$config Singleton::get(config);$config[debug] true;$config2 Singleton::get(config);echo debug: . ($config2[debug] ? true : false) . \n;?超全局变量在脚本的任何地方都能访问不用global声明。php// 超全局变量// $_GET, $_POST, $_REQUEST, $_SERVER, $_SESSION, $_COOKIE,// $_FILES, $_ENV, $GLOBALSecho 请求方法: {$_SERVER[REQUEST_METHOD]}\n;echo 请求URI: {$_SERVER[REQUEST_URI]}\n;echo 用户IP: {$_SERVER[REMOTE_ADDR]}\n;echo 用户代理: {$_SERVER[HTTP_USER_AGENT]}\n;// $_SERVER常用键$serverInfo [SERVER_SOFTWARE Web服务器,SERVER_NAME 服务器名,SERVER_PORT 端口,DOCUMENT_ROOT 文档根目录,REQUEST_TIME 请求时间,HTTP_HOST 主机名,HTTPS 是否HTTPS,];foreach ($serverInfo as $key $desc) {$value $_SERVER[$key] ?? 未知;echo $desc: $value\n;}??闭包变量的作用域跟普通函数类似但use关键字可以捕获外部变量。phpfunction makeCounter(): Closure{$count 0;return function () use ($count) {$count;return $count;};}$counter makeCounter();echo $counter() . \n; // 1echo $counter() . \n; // 2echo $counter() . \n; // 3?变量的生命周期在对象和资源上也适用。对象没有引用时会被垃圾回收。phpclass Resource{public string $name;public function __construct(string $name){$this-name $name;echo 创建: $name\n;}public function __destruct(){echo 销毁: {$this-name}\n;}}function createAndDestroy(): void{$obj new Resource(临时对象);// 函数结束$obj失去引用对象被销毁}createAndDestroy();$global new Resource(全局对象);unset($global);echo 脚本结束\n;?变量作用域有几个容易踩的坑。php// 坑1在循环中未重置变量$results [];for ($i 0; $i 5; $i) {$result $i * 2;// 忘了把$result加入$results}// $result是8不是数组// 坑2引用循环的副作用$arr [1, 2, 3, 4, 5];foreach ($arr as $value) {$value * 2;}// $value仍然是最后一个元素的引用// 再次使用$value可能导致意外修改unset($value); // 必须unset// 坑3全局变量污染function unsafeFunction(): void{// 使用了未声明的全局变量echo $GLOBALS[temp] ?? 未定义;}// 坑4超全局变量在CLI模式下有些键不存在if (php_sapi_name() cli) {echo CLI模式某些\$_SERVER键可能不存在\n;}?理解变量的作用域和生命周期能帮你写出更可预测的代码。特别是在大型项目中变量冲突和意外修改是常见的bug来源。用好作用域规则再加上一些编码规范这些问题都能避免。
PHP变量作用域与生命周期指南
发布时间:2026/6/3 23:53:56
PHP变量作用域与生命周期指南理解变量的作用域和生命周期是写好PHP代码的基础。PHP的变量作用域规则跟C语言有些像但又有自己的特点。PHP有局部变量、全局变量、静态变量和超全局变量几种。每种的作用域和生命周期都不一样。php// 全局变量$globalVar 全局变量;function testScope(): void{// 局部变量$localVar 局部变量;echo $localVar . \n;// 在函数内访问全局变量需要用global关键字global $globalVar;echo $globalVar . \n;// 或者用$GLOBALS数组echo $GLOBALS[globalVar] . \n;// 静态变量static $count 0;$count;echo 调用次数: $count\n;}testScope();testScope();testScope();// echo $localVar; // 报错局部变量在函数外不可访问?静态变量的生命周期贯穿整个请求。在函数内用static声明的变量函数退出后不会销毁下次调用时上次的值还在。phpfunction fibonacciGenerator(): Closure{return function () {static $a 0;static $b 1;$current $a;$next $a $b;$a $b;$b $next;return $current;};}$fib fibonacciGenerator();for ($i 0; $i 10; $i) {echo $fib() . ;}echo \n;?变量引用用符号多个变量可以指向同一个值。php// 引用赋值$a 10;$b $a; // $b引用$a$b 20; // 修改$b$a也变了echo a: $a, b: $b\n; // a: 20, b: 20// 引用传参function addItem(array $arr, mixed $item): void{$arr[] $item; // 直接修改原数组}$list [1, 2, 3];addItem($list, 4);print_r($list); // [1, 2, 3, 4]// 引用返回class Singleton{private static array $instances [];public static function get(string $key): mixed{if (!isset(self::$instances[$key])) {self::$instances[$key] [];}return self::$instances[$key]; // 返回引用}}$config Singleton::get(config);$config[debug] true;$config2 Singleton::get(config);echo debug: . ($config2[debug] ? true : false) . \n;?超全局变量在脚本的任何地方都能访问不用global声明。php// 超全局变量// $_GET, $_POST, $_REQUEST, $_SERVER, $_SESSION, $_COOKIE,// $_FILES, $_ENV, $GLOBALSecho 请求方法: {$_SERVER[REQUEST_METHOD]}\n;echo 请求URI: {$_SERVER[REQUEST_URI]}\n;echo 用户IP: {$_SERVER[REMOTE_ADDR]}\n;echo 用户代理: {$_SERVER[HTTP_USER_AGENT]}\n;// $_SERVER常用键$serverInfo [SERVER_SOFTWARE Web服务器,SERVER_NAME 服务器名,SERVER_PORT 端口,DOCUMENT_ROOT 文档根目录,REQUEST_TIME 请求时间,HTTP_HOST 主机名,HTTPS 是否HTTPS,];foreach ($serverInfo as $key $desc) {$value $_SERVER[$key] ?? 未知;echo $desc: $value\n;}??闭包变量的作用域跟普通函数类似但use关键字可以捕获外部变量。phpfunction makeCounter(): Closure{$count 0;return function () use ($count) {$count;return $count;};}$counter makeCounter();echo $counter() . \n; // 1echo $counter() . \n; // 2echo $counter() . \n; // 3?变量的生命周期在对象和资源上也适用。对象没有引用时会被垃圾回收。phpclass Resource{public string $name;public function __construct(string $name){$this-name $name;echo 创建: $name\n;}public function __destruct(){echo 销毁: {$this-name}\n;}}function createAndDestroy(): void{$obj new Resource(临时对象);// 函数结束$obj失去引用对象被销毁}createAndDestroy();$global new Resource(全局对象);unset($global);echo 脚本结束\n;?变量作用域有几个容易踩的坑。php// 坑1在循环中未重置变量$results [];for ($i 0; $i 5; $i) {$result $i * 2;// 忘了把$result加入$results}// $result是8不是数组// 坑2引用循环的副作用$arr [1, 2, 3, 4, 5];foreach ($arr as $value) {$value * 2;}// $value仍然是最后一个元素的引用// 再次使用$value可能导致意外修改unset($value); // 必须unset// 坑3全局变量污染function unsafeFunction(): void{// 使用了未声明的全局变量echo $GLOBALS[temp] ?? 未定义;}// 坑4超全局变量在CLI模式下有些键不存在if (php_sapi_name() cli) {echo CLI模式某些\$_SERVER键可能不存在\n;}?理解变量的作用域和生命周期能帮你写出更可预测的代码。特别是在大型项目中变量冲突和意外修改是常见的bug来源。用好作用域规则再加上一些编码规范这些问题都能避免。