sort()会丢失键名,索引数组重排为0,1,2…,关联数组键值关系被打乱;需保留键名时应使用asort()、ksort()或uasort()。

PHP里直接用sort()会丢失键名,要小心
如果数组是索引数组(数字下标),sort()能用,但会重排键名变成 0,1,2…;如果是关联数组(字符串键名),它会直接打乱键值对应关系。比如 ['a' => 10, 'b' => 5] 经过 sort() 后变成 [0 => 5, 1 => 10],原始键名全丢了。
实操建议:
- 只对纯数字索引、且不关心原键名的数组用
sort() - 想保留键名就别用
sort(),改用asort()(按值升序)、ksort()(按键升序)或uasort()(自定义比较) -
asort()和ksort()都是原地修改,不返回新数组,返回布尔值表示是否成功
按值排序又想保留键名,用asort()或arsort()
这是最常见需求:比如用户列表按年龄升序排,但还得通过用户名查数据,键名不能丢。
示例:
立即学习“PHP免费学习笔记(深入)”;
$users = ['alice' => 28, 'bob' => 22, 'carol' => 31]; asort($users); // 结果:['bob' => 22, 'alice' => 28, 'carol' => 31]
注意点:
-
asort()升序,arsort()降序 - 它们默认按字符串规则比较,数值可能被当字符串排(比如 10 排在 2 前面)——需要数值排序时加
SORT_NUMERIC标志:asort($users, SORT_NUMERIC) - 不支持多维数组直接排序,比如
['a' => ['score' => 85]],得用uasort()
要按数组内部字段排序,必须用uasort()配匿名函数
比如用户数据是二维数组:$list = [['name'=>'A','age'=>25], ['name'=>'B','age'=>20]],想按 age 排,asort() 完全无效。
正确写法:
uasort($list, function($a, $b) {
return $a['age'] <=> $b['age']; // PHP 7+ 船舰操作符,自动处理大小关系
});
关键细节:
- 回调函数必须返回整数:负数($a 在前)、0(相等)、正数($b 在前)
- 用
比写if-else更安全,避免漏掉相等情况 - 如果字段可能不存在,先做判断,否则会触发 Notice:
return ($a['age'] ?? 0) ($b['age'] ?? 0) -
uasort()保持键名,usort()不保持(键名重置为数字),选哪个看你要不要原键
中文字符串排序要用collator扩展,sort()会乱码
直接对中文数组调 sort() 或 asort(),结果通常是按 Unicode 码点排,不是字典序。“张三”可能排在“李四”后面,因为“张”的 Unicode 大于“李”。
解决方法是启用 intl 扩展,用 Collator:
$collator = new Collator('zh_CN');
$collator->asort($chineseArray);
没装扩展的话,临时方案是用 array_multisort() 配 mb_convert_encoding() 转拼音首字母,但稳定性差,容易出错。
真正上线项目,别绕开 intl —— 缺失这个扩展时,Collator 类根本不存在,class_not_found 错误比排序错更难排查。



















