array_unique默认区分大小写,需手动预处理;推荐用strtolower建临时键映射保留首次出现值;二维数组须用serialize+小写哈希判重,业务字段大小写策略需人工界定。

array_unique 默认区分大小写,必须手动预处理
array_unique() 本身不提供“忽略大小写”的开关。它默认用 SORT_STRING 比较,而 "Apple" 和 "apple" 在字符串比较下就是两个不同值。你不能靠传参(比如加 SORT_FLAG_CASE)让它自动忽略大小写——这个 flag 并不存在,PHP 不支持直接组合进 array_unique() 的 flags 参数。
推荐做法:先转小写建临时键,再取原始值
最稳妥、可读性强、且不破坏原始数据的方法是用关联数组做映射:
- 遍历原数组,把每个元素转成小写作为临时键,原始值作为对应值
- 重复的小写键会被自动覆盖,最终只保留**最后一次出现的原始值**(注意这点)
- 如果要保留**第一次出现的原始值**,就得用
!isset($map[strtolower($v)])判断
示例代码:
$arr = ['Apple', 'apple', 'Banana', 'banana', 'Orange'];
$map = [];
foreach ($arr as $v) {
$key = strtolower($v);
if (!isset($map[$key])) {
$map[$key] = $v; // 保留首次出现的原始值
}
}
$result = array_values($map); // 只取值,丢弃临时键
// $result === ['Apple', 'Banana', 'Orange']
别用 array_flip + array_flip 做大小写去重
有人想走捷径:array_flip(array_flip(array_map('strtolower', $arr))),这会出问题:
- 先全转小写 →
['apple','apple','banana','banana','orange'] - 第一次
array_flip后只剩三个键:['apple'=>3, 'banana'=>3, 'orange'=>4](键被覆盖,值变成最后索引) - 第二次翻转会把数字索引当值,结果变成
[3=>'apple', 3=>'banana', 4=>'orange']—— 直接语法错误或丢失数据
这种链式调用在大小写场景下不可控,容易踩坑,不建议用于生产。
二维数组或含结构数据时,必须序列化+哈希判重
如果你的数组里是关联子数组(比如用户记录),strtolower() 就没用了。这时得靠 serialize() 生成唯一指纹:
- 对每个子数组先
serialize(),再转小写(如果字段本身要忽略大小写) - 用该字符串作键存入临时
$seen数组 - 注意:
serialize()对键顺序敏感,确保输入结构一致
简单示意:
$users = [
['name' => 'Alice', 'email' => 'A@B.COM'],
['name' => 'Bob', 'email' => 'a@b.com'],
];
$seen = [];
$result = [];
foreach ($users as $user) {
$fingerprint = strtolower(serialize($user));
if (!isset($seen[$fingerprint])) {
$seen[$fingerprint] = true;
$result[] = $user;
}
}
真正麻烦的从来不是“怎么写”,而是“哪一层该忽略大小写”——email 字段要,但 ID 字段绝不能。这个边界得由业务逻辑定,没法交给一个通用函数兜底。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











