array_unique($arr, sort_regular) 对二维数组无效,因子数组不可直接比较,php 会尝试转为字符串导致全部变为"array"而只剩一个;应改用 array_map('serialize', $arr) 配合 array_unique 再 unserialize,或按字段键去重。

PHP 8.2 中 array_unique 的 SORT_REGULAR 模式不能直接用于二维数组去重,因为它只支持一维数组(即数组的每个元素必须是标量或 null)。对二维数组调用 array_unique($arr, SORT_REGULAR) 会触发警告(Warning: array_unique(): Expected parameter 1 to be an array, object given 或更常见的是“Array to string conversion”错误),因为 PHP 尝试将子数组隐式转为字符串作比较,而默认行为不可靠且不保证逻辑正确。
为什么 SORT_REGULAR 对二维数组无效
SORT_REGULAR 是 array_unique 的第二个参数,仅控制「如何比较元素」,但它要求所有元素可被 PHP 直接比较。二维数组中每个元素本身是数组——而数组在 PHP 中不可哈希、不可直接用 == 或 === 稳定比较(尤其含浮点数、NaN、对象或递归结构时)。PHP 底层在去重过程中会尝试把子数组转成字符串(如 Array),导致所有子数组变成相同字符串,最终只剩一个元素。
替代方案:用 array\_map + serialize 去重(推荐)
最常用且兼容 PHP 8.2 的做法是先序列化每个子数组为唯一字符串,去重后再反序列化:
- 确保子数组不含资源、闭包或无法序列化的对象(否则
serialize()失败) - 使用
array_map('unserialize', ...)还原时注意安全性(仅处理可信数据) - 示例代码:
$data = [
['id' => 1, 'name' => 'Alice'],
['id' => 2, 'name' => 'Bob'],
['id' => 1, 'name' => 'Alice'], // 重复
];
$serialized = array_map('serialize', $data);
$unique_serialized = array_unique($serialized);
$result = array_map('unserialize', $unique_serialized);
// $result 包含两个唯一子数组
更健壮的方式:自定义比较 + usort + 遍历去重
若需精确控制比较逻辑(比如忽略键顺序、忽略空值、按特定字段去重),应手动实现:
- 用
usort先排序(可选,便于相邻比较) - 遍历并用
array_diff_assoc或==判断是否已存在 - 或使用
array_reduce累积唯一项(适合小到中等规模数组) - 示例(按 'id' 字段去重):
$seen = [];
$result = [];
foreach ($data as $item) {
if (!isset($seen[$item['id']])) {
$seen[$item['id']] = true;
$result[] = $item;
}
}
PHP 8.2 新特性提示:无内置二维数组去重函数
截至 PHP 8.2,array_unique 仍未支持多维数组。RFC(如 array_unique_multidimensional)曾被提出但未被采纳。因此不要依赖未来特性,生产环境请坚持用 serialize 或字段级去重逻辑。注意 json_encode($item, JSON_FORCE_OBJECT) 也可替代 serialize(更安全、无反序列化风险),但需确保数据不含资源、资源句柄或循环引用。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











