最快是array_merge(...$arr),仅适用于子数组全为数字索引;含字符串键时用array_reduce+array_merge更安全;结构不规则或需加工数据则用foreach最可控。

用 array_merge(...$arr) 最快,但只适用于「子数组键名全是数字」的场景
如果二维数组每个子数组都是索引数组(比如 [[1,2], [3,4], [5]]),直接解包合并是最快最干净的方式。PHP 5.6+ 支持展开操作符 ...,array_merge() 会把每个子数组平铺进来。
常见错误:传入 array_merge($arr)(没展开)——结果还是原二维数组;或者子数组含字符串键(如 ['a' => 1]),这时 array_merge 会按键名覆盖而非追加,导致数据丢失。
实操建议:
- 确认所有子数组是纯数字索引:
array_values($sub)可临时规整 - 避免嵌套更深:该方法只展一层,
[[[1,2]], [3]]不会变成[1,2,3] - 性能好,无循环开销,适合大数组
array_reduce + array_merge 通用稳妥,兼容关联键名
当子数组含字符串键(如 [['id'=>1], ['name'=>'foo']]),或不确定键类型时,array_reduce 是更安全的选择。它逐个累积合并,不依赖键名规则。
立即学习“PHP免费学习笔记(深入)”;
示例:
$flat = array_reduce($arr, function($carry, $item) {
return array_merge($carry, $item);
}, []);
注意点:
- 初始值必须是空数组
[],否则第一次合并会出错 - 比
array_merge(...$arr)略慢(有回调函数调用开销),但差距微小 - 不会自动去重或过滤空值,如有需要得额外处理
遇到「子数组里还有数组」?别硬 flatten,先明确需求层级
真正的难点往往不在「二维→一维」,而在于你拿到的其实不是标准二维数组。比如 [1, [2, [3, 4]], 5] ——这属于不规则嵌套,array_merge 或 array_reduce 都只会展一层,结果是 [1, 2, [3, 4], 5],第三层还在。
这时候要问自己:是否真需要完全扁平?有没有可能只需要提取某一层字段(比如所有 'name')?
实操建议:
- 先
var_dump(array_keys($arr[0]))看结构,别猜 - 若确实需全深度扁平,用递归函数或
iterator_to_array(new \RecursiveIteratorIterator(new \RecursiveArrayIterator($arr))),但要注意性能和内存 - 多数业务场景中,用
array_column($arr, 'field')提取单列更直接
用 foreach 手动合并最可控,适合带条件过滤
当转换过程需要判断、跳过空子数组、转换值类型、或去重时,显式 foreach 反而是最清晰的选择。没有魔法,逻辑一目了然。
示例(跳过空子数组并转字符串):
$flat = [];
foreach ($arr as $sub) {
if (!is_array($sub) || empty($sub)) continue;
foreach ($sub as $v) {
$flat[] = (string)$v;
}
}
关键点:
- 避免隐式类型转换陷阱:比如
$flat = array_merge($flat, $sub)在循环里反复调用,性能差 - 可随时插入
if判断,比如只合并isset($sub['status']) && $sub['status'] === 'active'的项 - 调试方便:中间
echo或var_dump不影响结构
array_merge(...$arr) 就够了;剩下两成,看子数组键名是否混杂——混杂就上 array_reduce;再碰到结构不规整或要加工数据,foreach 是最不容易翻车的底线。别为了“一行代码”牺牲可读性和健壮性。



















