array_unique 保留原始键名但不重排,导致键不连续;array_flip 因值重复引发键覆盖;浮点数等非字符串/整数键会被强制类型转换;sort 等函数才真正重置键名。

array_unique 保留键名但不保证连续性
很多人以为 array_unique “丢了键名”,其实它根本没丢——只是没重排、也没补空。它严格保留首次出现元素的原始键,跳过重复项后,中间空缺的键就自然留下来了。
比如:$data = ['a' => 'x', 'b' => 'y', 'c' => 'x']; → array_unique($data) 结果是 ['a' => 'x', 'b' => 'y'],c 被剔除,a 和 b 的键原样留下。这不是丢失,是“按原位置摘果子”。
- 关联数组(字符串键):键名完整保留
- 索引数组(数字键):键名也保留,但可能不连续(如
[0 => 'a', 2 => 'b']) - 混合键数组:PHP 自动做类型归一(
"1"、1、1.0都变1),冲突时后者覆盖前者
array_flip 后键名“消失”其实是值冲突覆盖
array_flip 不是转换失败,而是把原数组的 值 当新键用。一旦原数组有重复值,新键就会撞车——PHP 数组不允许重复键,所以后出现的必然覆盖先出现的。
例如:$arr = ['a' => 'apple', 'b' => 'banana', 'c' => 'apple']; → array_flip($arr) 得到 ['apple' => 'c', 'banana' => 'b']。看起来 a 没了,其实是 apple 这个键被 c 覆盖了。
立即学习“PHP免费学习笔记(深入)”;
- 必须提前检查:
count($arr) !== count(array_unique($arr))就说明有重复值,不适合直接array_flip - 若需保留所有映射,改用
array_reduce手动构建值→键数组,对重复值存成数组(如'apple' => ['a', 'c']) - 浮点数、布尔、
null作原值时会被强制转为整型或字符串,极易引发隐式覆盖
你以为在“转换”,其实 PHP 在悄悄做类型归一
PHP 数组键名只接受整数和字符串两种类型,其他类型会强制转换:
-
1.5、true、"1"、"01"全部变成整数1,最后赋值者胜出 -
"1.5"是合法字符串键,不会转;但1.5(float)作键时会被截断为1 - 这种转换发生在赋值瞬间,不是
array_unique或array_flip导致的,但会让开发者误以为“函数搞丢了键”
验证方法:var_dump(array_keys($arr)); 看实际存进去的是什么类型和值。
真正“丢键”的常见操作其实是这几种
不是所有键名异常都怪 array_unique 或 array_flip。下面这些操作才是真·重置键名:
-
sort()、rsort():无条件重排为0,1,2...,原始键全丢 -
array_values(array_unique($arr)):先去重再取值,等于主动放弃键名 - 用
foreach+[]重建数组:新数组默认数字键,除非显式写$new[$k] = $v; - JSON 编解码:
json_decode(json_encode($arr), true)会抹掉字符串键的顺序和部分类型特征
关键区别在于:是否显式调用了重索引函数,或是否无意中触发了 PHP 的自动键归一逻辑。遇到“键没了”,先查 var_dump(array_keys($arr)),别急着怪去重函数。



















