PHP 8.1 正式支持字符串键关联数组的展开运算符解包合并,同名键后值覆盖前值,数字键保留原键名不重索引,语法简洁高效,适用于扁平配置合并场景。

PHP 8.1 正式支持对关联数组(即含字符串键的数组)使用展开运算符([...$array])进行解包合并,不再像早期版本那样仅限索引数组。这使得配置合并、环境差异化拼装等场景更简洁、语义更清晰。
基本用法:直接解包两个关联数组
只需用方括号包裹多个数组变量,即可完成扁平合并:
- 同名字符串键,后出现的值覆盖前一个(与
array_merge()行为一致) - 数字键保留原键名,不重索引(这点和
array_merge()不同) - 所有数组必须是真实数组,不能是
null或非数组类型,否则报错
示例:
$default = ['host' => 'localhost', 'port' => 3306, 'debug' => false]; $prod = ['host' => 'db.example.com', 'debug' => true]; $config = [...$default, ...$prod]; // PHP 8.1+ 支持 // 结果:['host' => 'db.example.com', 'port' => 3306, 'debug' => true]
合并多个关联数组(含动态数量)
当数组数量不确定时,可先收集到一个数组中,再用 ... 展开:
- 适用于从配置文件、环境判断、模块加载等场景动态拼接配置
- 注意:不能直接写
[...$list],其中$list必须是数组的数组,如[['a'=>1], ['b'=>2]]
正确写法:
修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
$parts = [
['log_level' => 'info'],
$_ENV['DEBUG'] ?? [],
$cacheConfig ?? [],
];
$final = [...$parts[0], ...$parts[1], ...$parts[2]]; // 显式展开
// 或更灵活地用 array_merge(...$parts) —— 注意:这是 array_merge + 展开,不是纯语法解包
⚠️ 提示:纯展开语法 [...$arr] 要求 $arr 是单个数组;若想“展开一个数组列表”,需配合 array_merge(...$list)。
和 array_merge 的关键区别
别把展开运算符当成 array_merge 的简写,它们定位不同:
-
[...$a, ...$b]是语法级操作,无函数调用开销,保留所有原始键(包括数字键) -
array_merge($a, $b)会强制重排数字键(变成0,1,2...),但能静默跳过null或非数组参数(需注意警告) - 展开运算符不支持递归,遇到嵌套数组只是整体替换(例如
'db' => [...$dbConf]可以,但不会自动合并db.host和db.port)
实用建议:什么时候优先用展开?
适合以下情况:
- 配置项结构扁平,且明确以字符串键为主(如 Laravel 配置风格)
- 需要保持数字键原样(比如带顺序的中间件列表:
[0=>'Auth', 1=>'Cors']) - 代码可读性优先,希望合并逻辑一目了然,不依赖函数语义
- 运行环境确定为 PHP 8.1+,无需兼容旧版本
不适合:
- 需递归合并多维配置(此时该用
array_merge_recursive或array_replace_recursive) - 输入来源不可控(如可能含
null),又不想加is_array()判断 - 要保留左侧键优先(此时
+运算符更合适)
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










