php数组排序核心陷阱:sort()丢键名,关联数组须用asort()/arsort();uasort()回调须返整数;array_multisort()易错,推荐usort();中文排序需collator或拼音,非默认ascii。

sort() 和 asort() 用错就丢键名
PHP 数组排序函数最常踩的坑,是没分清「重排值」和「重排键值对」。比如 sort() 会把关联数组的键全砍掉,变成数字索引;而你要保留原始键名(比如 ['user_id' => 123, 'name' => 'Alice']),必须用 asort()。
常见错误现象:sort() 后 foreach ($arr as $key => $val) 里 $key 全变成 0, 1, 2...,数据结构直接崩了。
- 数值数组、不关心键名 → 用
sort()、rsort() - 关联数组、要按值排序且保留键 → 必须用
asort()(升序)或arsort()(降序) - 要按键名本身排序 → 改用
ksort()/krsort(),不是按值
uasort() 自定义排序写错回调函数就静默失败
uasort() 看似灵活,但回调函数返回值不对,排序就完全不生效,也不报错——这是 PHP 的老毛病。它要求回调必须返回整数:负数(a )、0(相等)、正数(<code>a > b),不能返回布尔值或字符串。
使用场景:按嵌套字段排序,比如数组里每个元素是 ['score' => 87, 'level' => 'hard'],想按 score 降序。
立即学习“PHP免费学习笔记(深入)”;
示例(正确):
uasort($users, function($a, $b) { return $b['score'] - $a['score']; });- 别写
return $a['score'] > $b['score'];(返回 true/false,无效) - 涉及字符串比较时,用
strcmp($a['name'], $b['name']),别直接减 - 回调里访问不存在的键会触发 notice,建议先
isset()或用空合并$a['score'] ?? 0
多维数组排序别硬套 array_multisort()
array_multisort() 表面强大,实际写起来极易出错:它要求先把要排序的列单独抽成一维数组,再跟原数组一起传进去,参数顺序、引用关系、数组长度必须严丝合缝。稍有不一致,要么报 warning,要么排得乱七八糟。
更稳的替代方案是用 usort() + 匿名函数,逻辑直给,调试也方便。
- 抽列写法易错点:
array_column($data, 'price')返回的数组长度必须和$data一致,否则错位 -
usort()中可直接访问$a['price']和$b['price'],不用预处理 - 如果要同时按 price 升序、name 降序,
usort()里写两个 if 判断更可控,array_multisort()得配一堆参数
中文字符串排序默认按 ASCII,不是按拼音
用 sort() 或 usort() 排中文数组,比如 ['张三', '李四', '王五'],结果往往是乱序,因为 PHP 默认按字节比较,而 UTF-8 下中文是多字节,ASCII 值根本不能反映字典序。
解决办法不是换函数,而是换比较逻辑:
- 简单场景:用
Collator类(ICU 扩展需启用),$coll = new Collator('zh_CN'); $coll->asort($arr); - 没 ICU?临时转拼音(用第三方库如
overtrue/pinyin),再按拼音字符串排序 - 别试图用
mb_strtolower()或iconv()混搭,UTF-8 下这些不解决排序逻辑问题
这个点容易被忽略:本地测试看着正常,一上生产环境字符集配置不同,中文排序就翻车。










