PHP交换变量有三种写法:1. list()或数组解构(PHP 5.4+/7.1+)最简洁但仅适用于已初始化标量,不支持引用和超全局变量;2. 临时变量法最稳妥,兼容所有版本,支持任意类型和显式引用;3. extract()+compact()是反模式,禁止生产使用。

PHP 交换两个变量的三种常用写法
直接用 list() 或数组解构(PHP 7.1+)最简洁,但要注意类型和引用陷阱;临时变量法最稳妥,适合所有版本和复杂场景。
用 list() 一行交换(PHP 5.4+)
这是最常被搜到的“炫技”写法,本质是数组赋值的语法糖:
list($a, $b) = [$b, $a];
常见错误现象:Undefined variable —— 如果 $a 或 $b 未定义,右侧数组会报错;list() 不支持引用交换,原变量若为对象或数组,只是交换了值拷贝,不是地址。
- 仅适用于已初始化的标量变量(int、string、bool 等)
- PHP 7.1+ 可用更直观的写法:
[$a, $b] = [$b, $a]; - 不能用于超全局变量或表达式(如
list($_GET['x'], $_GET['y']) = ...会报错)
用临时变量最安全(兼容所有 PHP 版本)
看似啰嗦,但逻辑清晰、无隐式行为、支持任意类型(包括资源、对象引用):
立即学习“PHP免费学习笔记(深入)”;
$tmp = $a;<br>$a = $b;<br>$b = $tmp;
使用场景:函数内交换参数、处理数据库字段映射、避免因优化导致的意外行为(比如某些 opcode 缓存对 list() 的处理不一致)。
- 不会触发任何魔术方法(
__get/__set) - 可配合
&显式传引用:function swap(&$a, &$b) { $tmp = $a; $a = $b; $b = $tmp; } - 性能差异可忽略——现代 PHP 引擎对三行赋值优化得很好
用 extract() + compact() 是反模式
网上偶见这种写法:extract(compact('b', 'a'));,看起来像交换,实际是覆盖变量作用域,极易引发意外覆盖(比如当前已有 $c,而 compact() 返回更多键)。
它不交换,只是把 $b 的值赋给 $a,再把 $a 的旧值赋给 $b,但依赖变量名字符串,无法静态分析,调试困难。
- 禁止在生产环境使用
- PHP 8.0+ 中
extract()默认不覆盖已有变量,行为更不可控 - IDE 和静态分析工具(如 PHPStan)会直接报
Unresolvable extract
真正要注意的是:如果变量本身是引用($b = &$a;),任何交换操作都会同时影响两者,这时候必须先 clone 或 unset 引用关系——这点几乎没人提,但线上出过 bug。



















