PHP 5.6+ 可用 array_merge(...$arr) 展开索引型二维数组为一维,但不适用于关联键嵌套;去重须先 array_merge 再 array_unique,必要时用 array_values 重排索引,并注意类型敏感与性能问题。

用 array_merge(...$arr) 展开二维数组
PHP 5.6+ 支持展开运算符,直接把二维数组的每个子数组当作参数传给 array_merge(),就能合并成一维。注意:只适用于「索引数组嵌套索引数组」这种结构,比如 [ [1,2], [2,3], [4] ]。
常见错误是误用 array_merge($arr)(没加 ...),结果只是把整个二维数组当第一个参数传进去,返回原样。
- ✅ 正确写法:
$flat = array_merge(...$arr); - ❌ 错误写法:
$flat = array_merge($arr);(返回仍是二维) - ⚠️ 如果子数组是关联键(如
['a'=>1, 'b'=>2]),array_merge会重置键名,数值键变 0/1/2…,关联键会被覆盖或追加,不保留原始键
去重必须在展开后调用 array_unique()
array_unique() 只能处理一维数组,对二维直接报 Warning:「Array to string conversion」。所以顺序不能错:先展开,再去重。
另外,默认行为会保留原始键名,导致返回数组键不连续(比如 [0=>1, 2=>2, 4=>3])。如果后续要遍历或 JSON 输出,建议加 array_values() 重排索引。
立即学习“PHP免费学习笔记(深入)”;
- ✅ 推荐链式写法:
$result = array_values(array_unique(array_merge(...$arr))); - ⚠️
array_unique()对字符串和数字类型敏感:'1'和1被视为不同值;若需松散比较,得先统一类型(如全转字符串或全转 int) - ⚠️ 大数组时性能下降明显,因为
array_unique()内部逐个比较,没有哈希优化
遇到关联键或混合结构怎么办
如果二维数组是 [ ['id'=>1, 'name'=>'a'], ['id'=>2, 'name'=>'b'] ] 这种对象式结构,array_merge(...$arr) 会把每个子数组合并成一个大数组,键名冲突(比如多个 'id'),最终只剩最后一个值 —— 这通常不是你想要的「扁平化」。
此时应明确目标:你是想提取某列(如所有 'id' 值)?还是把所有值无差别拉出来?
- 提取单列去重:
$ids = array_unique(array_column($arr, 'id')); - 彻底展平所有值(不管键名):
$flat = []; array_walk_recursive($arr, function($v) use (&$flat) { $flat[] = $v; }); $result = array_values(array_unique($flat)); -
array_walk_recursive()能穿透多层,但会跳过键为数字的子数组(PHP 行为),且无法区分 null / false / 0 的原始值
注意 array_unique() 的返回类型陷阱
它返回的是数组,但值类型不变 —— 如果原数组里有字符串数字(如 '123')、整数(123)、浮点数(123.0),默认不会自动转换或合并。看起来去重了,其实可能漏掉逻辑重复项。
比如 [123, '123', 123.0] 经 array_unique() 后仍是三个元素。真要去重语义值,得先标准化:
- 全转字符串:
array_unique(array_map('strval', $flat)) - 全转整型(适合 ID 类):
array_unique(array_map('intval', $flat)) - 或者用
array_unique($flat, SORT_REGULAR)(默认就是这个标志),但注意它仍不做类型转换
真正难处理的是嵌套含 null、空数组、对象的情况 —— array_walk_recursive() 会跳过对象,array_merge(...$arr) 会报错,这时候得手写递归或用 json_encode() 做唯一性标记,代价更高。










