array_unique() 对多维数组无效,因其将子数组转为字符串时均得“array”,致仅留首项;应改用 foreach+isset() 构建唯一索引,或 array_column()+array_intersect_key() 配合索引映射。

用 array_unique() 直接去重会失败,因为默认只比较数组值的字符串形式
PHP 的 array_unique() 对多维数组无效——它把每个子数组当成一个对象,而 PHP 7+ 中数组不能直接转为字符串,结果所有子数组都变成 Array 字符串,最终只保留第一个。你看到的“去重后只剩一项”,基本就是这个原因。
真正可行的思路是:先提取你要依据的键(比如 'id' 或 'email'),生成唯一标识序列,再用该序列做索引过滤原数组。
按指定键提取并去重:用 foreach + isset() 构建唯一索引数组
这是最可控、兼容性最好(PHP 5.4+)的方法,不依赖额外扩展,也避免 array_column() 在含空值时的陷阱。
- 遍历原数组,用目标键的值作为临时键(如
$seen[$item['uid']] = true) - 只保留第一次出现的完整子数组,后续重复键值跳过
- 注意处理键不存在或为 null/0/false 的情况,建议用
isset($item[$key])判定
$unique = [];
$seen = [];
foreach ($data as $item) {
$keyValue = $item['uid'] ?? null;
if (isset($keyValue) && !isset($seen[$keyValue])) {
$seen[$keyValue] = true;
$unique[] = $item;
}
}
用 array_column() + array_intersect_key() 快速实现(PHP 7.4+ 更稳)
如果你确认目标键一定存在且值可作数组键(即不是浮点、对象、数组),可以用 array_column() 提取键值列,再配合 array_keys() 和 array_unique() 反向映射。
-
array_column($data, 'email')提取出所有 email 值 -
array_keys(array_unique(...))得到首次出现位置的索引 - 再用
array_intersect_key($data, ...)拿回对应子数组
⚠️ 注意:array_unique() 对字符串和数字敏感,'1' 和 1 会被视为相同;若业务要求严格类型区分,必须先 cast 类型或改用第一种方法。
遇到 null / 空字符串 / 0 值时怎么安全去重
很多线上 bug 出在这里:用户邮箱字段为空、ID 为 0、或数据库返回 null,导致多个 “空” 被当成同一项去重掉。
- 不要依赖
empty(),它会把0、"0"、null全判为真 - 显式检查是否为
null或缺失:用!isset($item[$key])或array_key_exists($key, $item) - 若允许空值参与去重(比如多个
null算一个),可改用json_encode($item[$key])作唯一键,但性能略低
实际写的时候,那个 ?? null 后面要不要加类型断言,取决于你的数据源是否可信——不可信就别省这一步。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











