二维数组扁平化应使用array_merge(...$arr)或call_user_func_array('array_merge', $arr),而非array_column;去重须用array_unique而非array_flip;大数组宜用foreach迭代避免栈溢出。

PHP 二维数组转一维:用 array_column 或 array_merge + call_user_func_array
直接用 array_column 只能提取某列(比如所有 'id' 或 'name'),不是真正“降维”。真要扁平化整个二维数组(比如把 [ [1,2], [3,4,5], [6] ] 变成 [1,2,3,4,5,6]),得用 array_merge(...$arr)(PHP 5.6+)或 call_user_func_array('array_merge', $arr)(兼容旧版)。
常见错误是写成 array_merge($arr) —— 少了展开操作符 ... 或没用 call_user_func_array,结果得到原数组本身,不是一维。
- 如果子数组键名不重要,用
array_merge(...$arr)最简洁 - 如果含非数值键(如
['a'=>1, 'b'=>2]),array_merge会重置键名为数字,若需保留键,得用foreach手动合并 - 嵌套超过两层?
array_merge不递归,此时该用array_walk_recursive
去重不能只靠 array_flip:它会丢键、删重复值、强制转字符串键
array_flip 的本意是交换键和值,不是去重工具。它要求输入数组的「值」必须能当合法键(即整数或字符串),且遇到重复值时,**后出现的会覆盖先出现的**——这看似“去重”,实则不可控,还可能把 0、false、'' 这类值误判为相同键而丢失数据。
例如:array_flip([0, false, '']) 结果只有 [0 => ''],因为三者转换为键后都变成 0。
立即学习“PHP免费学习笔记(深入)”;
- 真正安全去重用
array_unique($arr),它保留首次出现的键和值类型 - 若后续还要用键查值,再补一次
array_values重排索引即可 -
array_flip(array_flip($arr))是常见误区,等价于array_unique仅在值全为字符串/整数且无类型混用时偶然成立
组合操作:降维 + 去重 + 保证顺序,三步缺一不可
从二维数组到去重后的一维集合,典型链路是:降维 → 去重 → 重索引。中间任何一步出错,结果就不可靠。
示例:
$data = [['a', 'b'], ['b', 'c'], ['a', 'd']]; $result = array_values(array_unique(array_merge(...$data))); // 得到 ['a','b','c','d'],顺序由首次出现位置决定
- 漏掉
array_values:去重后键可能是[0=>a, 2=>b, 4=>c, 6=>d],影响遍历和 JSON 输出 - 用
array_flip替代array_unique:一旦数组里有null或0,结果直接错乱 - PHP 版本低于 5.6:必须用
call_user_func_array('array_merge', $data),否则报语法错误
性能注意点:大数组别用 array_merge(...) 展开
当二维数组元素极多(比如上千个子数组),array_merge(...$arr) 会把所有子数组作为参数压栈,可能触发 max_input_vars 或栈溢出。这时应改用迭代方式:
$flat = [];
foreach ($arr as $sub) {
foreach ($sub as $item) {
$flat[] = $item;
}
}
- 迭代写法内存更稳,适合处理 >10MB 的数据
-
array_unique对大数组本身也有开销,如只需判断存在性,建议边扁平边用isset($seen[$item])去重 - 若原始二维数组含对象或资源,
array_merge会报错,必须先用array_map提取标量字段
'1' 和 1 在 array_unique 中默认视为不同,但经 array_flip 后却变成同一键,导致隐性数据丢失。











