最简洁高效的方法是使用 array_merge(...$arrays),要求 PHP ≥ 5.6、$arrays 为二维索引数组且每个子数组均为一维数值数组;漏掉 ... 会导致警告或嵌套结构,含非数组元素或字符串键会出错或丢数据。

多个一维数组合并成一个扁平数组用 array_merge + ...
PHP 5.6+ 支持数组解包,array_merge(...$arrays) 是最简洁高效的写法,比 call_user_func_array('array_merge', $arrays) 更直观、性能更好。它要求 $arrays 是二维索引数组(如 [[1,2], [3,4], [5]]),内部每个子数组都是一维的。
常见错误现象:直接 array_merge($arrays) 会把整个二维数组当第一个参数,结果还是嵌套结构;漏掉 ... 解包符号,导致 Warning: array_merge() expects at least 1 parameter。
- 所有子数组必须是纯数值索引、一维结构;含字符串键或嵌套会丢失数据或报错
- 空子数组(如
[])会被跳过,不影响合并结果 - 若来源是 Collection,先调用
->toArray()再解包,别对 Collection 直接用...
Laravel 集合批量 concat 后必须加 values() 才能保证 JSON 数组格式
用 concat() 合并多个 Collection 时,结果保留原始键名 —— 若其中任一集合含字符串键(如 collect(['a' => 1]))或非连续数字键(如 collect([10 => 'x', 20 => 'y'])),拼接后键结构混乱,json_encode() 输出会变成对象而非数组。
正确做法是链式调用 ->values() 强制重置为连续数字索引:
$merged = collect([1, 2])
->concat(collect(['a' => 3]))
->concat(collect([4, 5]))
->values(); // → [1, 2, 3, 4, 5]
-
values()返回新集合,不修改原集合,必须重新赋值或继续链式调用 - 如果后续还要
groupBy()或map(),values()应放在concat()之后、其他操作之前 - 没加
values()的典型表现:API 返回{"0":1,"1":2,"a":3,"2":4,"3":5}而不是[1,2,3,4,5]
动态循环合并多个数组时优先用 array_reduce 而非 foreach + array_merge
当数组列表来自变量(如 $datasets = [$arr1, $arr2, $arr3, ...]),用 array_reduce() 更函数式、不易出错:
$all = array_reduce($datasets, function ($carry, $item) {
return array_merge($carry, (array) $item);
}, []);
相比手动 foreach 累加,array_reduce 天然处理空数组、null 和非数组类型(加 (array) 强转防崩)。
- 避免在循环里反复写
$result = array_merge($result, $next),容易漏初始化或覆盖 -
array_merge对非数组参数会警告,(array) $item是低成本兜底 - 若需去重,可在回调里套
array_unique(..., SORT_REGULAR),但注意性能损耗
嵌套数组扁平化别硬写递归,直接用 array_collapse 或 collapse()
Laravel 提供了专用于“二维变一维”的工具:array_collapse()(原生函数)和 Collection::collapse()(集合方法)。它们专治 [[1,2], [3,[4,5]], [6]] 这类结构 —— 注意:只展开一层,不递归。
常见误用:拿 array_merge(...$arr) 处理含非数组元素的二维结构(如 [[], null, [1,2]]),会报错;而 array_collapse() 自动跳过非数组项。
-
array_collapse([[1,2], null, [3]])→[1,2,3];array_merge(...[[1,2], null, [3]])直接报 Warning - Collection 场景下,
collect($nested)->collapse()比先map->toArray()再array_collapse少一次转换 - 要彻底递归扁平化(三层以上),才需
flatten()或自定义递归,日常二维够用collapse
实际项目里最容易被忽略的是键名残留问题:哪怕你只合并数值数组,只要中间某步用了带字符串键的 Collection 或手动构造了关联结构,concat() 就会把它带进去,最后 json_encode 出来是对象 —— 这个坑不打日志几乎看不到,得靠 var_dump 或 Postman 看原始响应体才能发现。











