PHP 7.2 中 array_unique() 不支持二维数组大小写不敏感去重,需先统一目标字段大小写再序列化或排序去重,推荐使用标准化后 serialize+in_array 或 usort+相邻去重方案。

PHP 7.2 的 array_unique() 默认不支持大小写不敏感比较,且原生不支持二维数组直接去重。要去除二维数组中“内容相同但字符串值大小写不同”的重复项(例如 ['name' => 'Tom'] 和 ['name' => 'tom'] 视为重复),需先统一规范字符串字段的大小写,再执行去重。
以下是实用、可靠、兼容 PHP 7.2 的做法:
统一字段大小写后序列化去重
适用于子数组结构固定、含文本字段(如 `name`、`email`、`title`)的场景。核心是:**标准化后再序列化比对**。- 提取需参与去重的字段(比如
name,email),对它们统一转为小写(或大写) - 构造一个“标准化副本”用于比对,原始数据仍保留原大小写
- 使用
serialize()+array_unique()去重,再映射回原始数组
function unique2DCaseInsensitive($arr, $fields = ['name']) {
$seen = [];
$result = [];
foreach ($arr as $item) {
// 创建标准化比对用的临时数组
$normalized = $item;
foreach ($fields as $field) {
if (isset($item[$field]) && is_string($item[$field])) {
$normalized[$field] = strtolower($item[$field]);
}
}
$key = serialize($normalized);
if (!in_array($key, $seen, true)) {
$seen[] = $key;
$result[] = $item; // 保留原始大小写
}
}
return $result;
}
// 示例
$data = [
['id' => 1, 'name' => 'Alice'],
['id' => 2, 'name' => 'bob'],
['id' => 3, 'name' => 'ALICE'],
['id' => 4, 'name' => 'Bob'],
];
print_r(unique2DCaseInsensitive($data, ['name']));
// 输出保留原始格式,但 ALICE 和 Alice 视为重复,只留第一个使用 SORT_REGULAR + 自定义标准化排序+相邻去重
适合数据量稍大、想避免多次 `serialize` 开销的场景。先标准化排序,再线性扫描去重。- 定义标准化回调(如所有字符串字段转小写)
- 用
usort()排序,确保相同语义项相邻 - 遍历一次,跳过与前一项标准化后完全相等的项
function unique2DCaseInsensitiveSort($arr, $fields = ['name']) {
// 标准化函数
$normalize = function($item) use ($fields) {
$copy = $item;
foreach ($fields as $f) {
if (isset($item[$f]) && is_string($item[$f])) {
$copy[$f] = strtolower($item[$f]);
}
}
return $copy;
};
// 深拷贝并排序(按标准化结果)
$sorted = $arr;
usort($sorted, function($a, $b) use ($normalize) {
$na = $normalize($a);
$nb = $normalize($b);
return $na == $nb ? 0 : ($na < $nb ? -1 : 1);
});
// 相邻去重
$result = [];
$prev = null;
foreach ($sorted as $item) {
$curr = $normalize($item);
if ($prev === null || $curr != $prev) {
$result[] = $item;
$prev = $curr;
}
}
return $result;
}仅针对单字段、有唯一标识时的高效方案
如果二维数组每个子项都有一个**语义唯一字段**(如邮箱、用户名),且只需按该字段大小写不敏感去重,可用 `array_column` + `array_change_key_case` 组合:function uniqueByFieldCI($arr, $field) {
if (empty($arr)) return [];
$keys = array_column($arr, $field);
$lowerKeys = array_map('strtolower', $keys);
// 去重:保留首次出现的索引
$uniqueIndices = [];
$seen = [];
foreach ($lowerKeys as $i => $k) {
if (!isset($seen[$k])) {
$seen[$k] = true;
$uniqueIndices[] = $i;
}
}
return array_intersect_key($arr, array_flip($uniqueIndices));
}
// 示例:按 name 字段大小写不敏感去重,保留第一次出现的完整行
$data = [
['id'=>1, 'name'=>'John'],
['id'=>2, 'name'=>'JOHN'],
['id'=>3, 'name'=>'jane'],
];
print_r(uniqueByFieldCI($data, 'name'));注意:以上方法均不修改原始数组的键名和非目标字段大小写,仅用于判断重复逻辑。
PHP 7.2 不支持 array_unique($arr, SORT_STRING | SORT_FLAG_CASE) 作用于二维数组,所以不能依赖 flag 参数实现;必须手动标准化。
立即学习“PHP免费学习笔记(深入)”;



















