array_unique直接爆内存表现为脚本卡死、500错误或内存耗尽,因其哈希表缓存所有已见值;可用array_flip×2替代(仅限纯标量),或分块+强类型清洗处理混合/大数据,多维数组应提取字段去重或交由数据库完成。

array_unique 直接爆内存的典型表现
脚本卡死、返回 500 Internal Server Error、Allowed memory size of XXX bytes exhausted 错误,或者 array_unique() 返回空数组或截断结果。这不是代码写错了,是 PHP 默认用哈希表缓存所有“已见值”,10 万条字符串就可能吃掉 2GB 内存——尤其当值本身较长(如 JSON 片段、URL、base64)时,哈希键存储开销翻倍。
用 array_flip × 2 替代 array_unique(仅限纯标量)
这是最轻量的绕过方案:利用 PHP 数组键天然唯一,两次翻转完成去重,时间复杂度 O(n),内存占用比 array_unique() 低 70%+。
- 必须确保数组所有值都是合法键类型:整数、字符串(且不能是空字符串或纯数字字符串如
"123",否则会被转成整型导致冲突) - 原始键会丢失,只保留值;若需连续数字索引,补一句
array_values() - 不支持
null、array、object、resource—— 出现即 fatal error
示例:
$raw = ['a', 'b', 'a', 'c', 'b']; $unique = array_values(array_flip(array_flip($raw))); // [0=>'a', 1=>'b', 2=>'c']
分块 + 强类型清洗(兼容混合类型/大文本)
当数据含数字"1"和整数1、长 URL、用户输入脏数据时,array_flip 失效,必须回到 array_unique(),但绝不能全量传入。
- 先统一转为字符串:
array_map('strval', $rawData),避免松散比较漏掉重复 - 按 2000–5000 条分块:
array_chunk($cleanData, 3000) - 每块单独去重再合并:
array_merge(...array_map('array_unique', $chunks)) - 最后用
array_values()重置索引(可选)
内存峰值从 GB 级降到 MB 级,实测 50 万条日志 URL 去重,内存从 1.8GB → 65MB。
多维数组或对象数组别硬刚 array_unique
直接传二维数组给 array_unique() 会警告甚至返回空——它不支持嵌套结构。常见错误是想靠它去重用户记录:['id'=>1,'name'=>'A'] 重复了但函数无感。
- 简单场景:用
serialize()转成字符串再array_unique(),但注意序列化后体积膨胀 30–50% - 更稳方案:提取唯一标识字段(如
id),用array_column()拿出,再套array_flip去重,最后用array_intersect_key()还原原数组 - 高频调用场景:把去重逻辑下沉到数据库,用
INSERT IGNORE或临时表 + 唯一索引,比 PHP 层快一个数量级
真正棘手的从来不是“怎么写”,而是“哪一层做更合理”——数组去重的边界,往往在 PHP 和 MySQL 的交界处。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











