array_flip()最快最安全,专为键值互换设计,但要求原数组值为string或int,否则警告并丢弃;重复值会导致后键覆盖前键;不支持多维数组,需递归处理。

用 array_flip() 最快最安全
直接调用 array_flip() 就能完成键值互换,它专为此设计,底层用 C 实现,性能好且处理边界清晰。
注意:原数组的值必须是合法的键类型(即 string 或 int),否则会触发警告并丢弃该元素。比如浮点数、null、数组、对象都会被跳过。
-
array_flip(['a' => 1, 'b' => 2])→[1 => 'a', 2 => 'b'] -
array_flip([1.5 => 'x'])→ 警告 + 返回空数组(因为1.5强转为1,但原始键不是整型) - 若原数组有重复值(如
['a' => 1, 'b' => 1]),后出现的键会覆盖先出现的,结果只剩一个1 => 'b'
手动遍历适用于需要容错或转换逻辑的场景
当你要保留非标量值、做类型修正、或记录冲突时,不能依赖 array_flip(),得自己写循环。
例如把所有值统一转成字符串再当新键,或遇到重复值时拼接原键名:
立即学习“PHP免费学习笔记(深入)”;
foreach ($arr as $key => $value) {
$newKey = (string) $value;
if (isset($flipped[$newKey])) {
$flipped[$newKey] .= ',' . $key;
} else {
$flipped[$newKey] = $key;
}
}
这种写法可控性强,但明显比 array_flip() 慢,且容易漏判 isset() 和 array_key_exists() 的语义差异。
关联数组和索引数组互换时要注意键丢失风险
PHP 索引数组本质是键为连续整数的关联数组。用 array_flip() 处理 [10, 20, 30](即 [0=>10, 1=>20, 2=>30])会得到 [10=>0, 20=>1, 30=>2] —— 新数组不再是“索引数组”,is_array() 仍为 true,但 array_values() 才能重排下标。
- 原数组含非数字键(如
['x'=>1, 'y'=>2])→ 互换后是标准关联数组 - 原数组是纯数字索引但值含重复(如
[1, 1, 2])→ 结果只有两个元素:[1=>1, 2=>2](注意:键1对应的是最后一个原键1,不是0)
多维数组不能直接用 array_flip()
array_flip() 只作用于一维,遇到子数组会报 Warning:“Can only flip STRING and INTEGER values!”,整个函数返回 false。
如果真要翻转嵌套结构的键值(比如把 ['user' => ['id' => 123]] 变成 ['user' => [123 => 'id']]),必须递归判断 + 单独处理每层的叶子值:
function array_flip_deep($arr) {
$result = [];
foreach ($arr as $k => $v) {
if (is_array($v)) {
$result[$k] = array_flip_deep($v);
} else {
$result[$v] = $k;
}
}
return $result;
}
但绝大多数业务里,该需求本身说明数据结构设计可能已偏离常规使用模式——先确认是否真需要这么做,而不是急着写递归。
真正容易被忽略的是:array_flip() 不修改原数组,但返回的新数组如果值本身是引用,翻转后键仍指向同一内存地址;而手动遍历时若用了 &$value,又没注意解除引用,可能引发意外修改。



















