array_merge(...$arr)是二维转一维最常用写法,因其利用解包将子数组作为独立参数传入,一次性拼接且无额外函数调用开销,但要求子数组均为索引数组且PHP≥5.6。

为什么 array_merge(...$arr) 是二维转一维最常用写法
因为 PHP 的 array_merge() 在接收到多个数组参数时,会把它们按顺序拼接;而解包操作符 ... 能把二维数组的每一行当作独立参数传入,绕过「合并单个数组」的语义限制。比循环 + array_merge() 或 foreach + [] 累加快得多,也比 call_user_func_array('array_merge', $arr) 更直观、无函数调用开销。
常见错误是直接写 array_merge($arr) —— 这只是把整个二维数组当第一个参数,返回原样;必须解包。
- 适用前提:二维数组的子数组都是索引数组(key 为数字),否则
array_merge()会重置字符串 key,导致数据“丢失”(其实是覆盖) - 若含关联子数组且需保留 key,不能用此法,得改用
foreach手动合并 - PHP 版本需 ≥ 5.6(支持
...解包)
怎样处理含非数字 key 的二维数组
如果子数组里有像 ['name' => 'a', 'id' => 1] 这样的关联结构,array_merge(...$arr) 会让所有同名 key 被后一个覆盖(比如多个 'name' 只留最后一个),这不是降维,是误操作。
此时应明确目的:
– 若想扁平化并保留层级标识(如变成 ['0_name', '0_id', '1_name', ...]),需手动遍历生成新 key;
– 若只是简单摊开所有值(忽略 key),可用 array_values(array_merge(...array_map('array_values', $arr))) 先清 key 再合并。
立即学习“PHP免费学习笔记(深入)”;
-
array_map('array_values', $arr)把每个子数组转成纯数字索引 - 再用
array_merge(...$cleaned)合并 - 最后套一层
array_values()确保结果也是纯数字索引(避免因 key 不连续产生 gap)
array_merge 和 array_reduce 性能差多少
在万级以下数据量,差别几乎感知不到;但实测 10 万个子数组(每个含 10 个元素)时,array_merge(...$arr) 比 array_reduce($arr, 'array_merge', []) 快约 3 倍——因为后者每次迭代都新建数组、拷贝内容,而解包版是一次性分配+填充。
-
array_reduce写法更函数式,但不是“更高级”,只是可读性因人而异 - 注意
array_reduce初始值必须是[],写成null或省略会导致警告或意外行为 - PHP 7.4+ 可用箭头函数简化:
array_reduce($arr, fn($carry, $item) => array_merge($carry, $item), []),但性能仍不如解包
遇到 Warning: array_merge(): Argument #1 is not an array 怎么办
这是最常踩的坑:二维数组里混入了非数组元素,比如 [ [1,2], null, [3,4] ] 或 [ [1,2], '', [3,4] ]。array_merge() 解包后会把 null 或空字符串当第一个参数,直接报错。
解决方式不是 try-catch,而是预过滤:
- 用
array_filter($arr, 'is_array')剔除非数组项 - 更稳妥可加类型校验:
array_filter($arr, fn($v) => is_array($v) && !is_object($v)) - 如果原始数据来自 JSON 解析,注意
null或空对象可能被转成null或空数组,需提前 normalize
降维本身不难,难的是你永远不知道上游给的二维数组里藏着什么。检查 is_array 这一步,线上环境别省。











