php 8.3 中不推荐用纯递归实现二维数组去重,因其本质是两两比较而非树状遍历,易导致时间复杂度高、键序敏感、索引不连续及不可序列化元素崩溃;应先标准化再用 array_unique(..., sort_regular)。

PHP 8.3 中,递归函数本身并不适合直接用于二维数组去重——因为去重的核心是“判断两个子数组是否完全相等”,而递归更适合展开、遍历或扁平化结构。不规则二维数组(如键名不统一、嵌套深度不一致、含空值或混合类型)更需谨慎比对,盲目递归反而易出错或性能低下。
为什么不用纯递归做去重
递归函数擅长处理“树状展开”或“逐层探入”,但去重本质是两两比较 + 去留决策。若强行用递归实现去重逻辑(比如每层递归负责比对一个子数组),会导致:
- 时间复杂度飙升至 O(n²×m),其中 m 是平均子数组长度;
- 键顺序敏感(['a'=>1,'b'=>2] 和 ['b'=>2,'a'=>1] 在 PHP 中默认不等);
- 无法天然保证结果索引连续,还需额外重排;
- 遇到不可序列化元素(如资源、闭包)时直接崩溃(PHP 8.3 仍不支持序列化这些类型)。
推荐方案:标准化 + array_unique(SORT_REGULAR)
PHP 8.3 已原生支持 array_unique($array, SORT_REGULAR) 直接处理二维数组,前提是子数组结构可被 PHP 内部全等比较识别。对不规则数组,先用轻量递归做“标准化”,再调用原生函数:
- 编写一个递归辅助函数,仅用于规范键序、过滤空值、转数字字符串等预处理(不用于去重逻辑本身);
- 例如:强制将所有子数组按键字母排序(
ksort($sub, SORT_STRING)),移除null键值对,把数字字符串转为整型; - 处理完后,直接调用
array_unique($cleaned, SORT_REGULAR)——PHP 8.3 的SORT_REGULAR模式能正确比较数组内容全等; - 最后用
array_values()重置数字索引。
针对真正不规则结构的稳妥做法
当子数组差异过大(如混有对象、资源、动态键名),建议放弃通用递归,改用明确标识字段去重:
- 提取业务唯一字段组合成哈希,例如:
md5($item['id'] . '|' . $item['email'] ?? ''); - 用该哈希作临时键,赋值覆盖:
$unique[$hash] = $item; - 取
array_values($unique)得到去重结果; - 此方式不依赖 PHP 内部比较逻辑,稳定可控,且天然跳过不可序列化问题。
附:一个安全的预处理函数示例
以下函数仅做标准化,不承担去重职责,可配合 array_unique(..., SORT_REGULAR) 使用:
if (!is_array($arr)) return $arr;
$clean = [];
foreach ($arr as $k => $v) {
if ($v === null || $k === '') continue;
$clean[(string)$k] = is_scalar($v) ? $v : normalizeSubArray($v);
}
ksort($clean, SORT_STRING);
return $clean;
}
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











