php数组排序不能只用sort(),因其重置键名、不支持关联数组按值排序、无法处理多维或自定义规则;应据场景选用asort()、usort()、uasort()或array_multisort()。

PHP 数组排序不能只靠 sort() —— 它会重置键名、不支持关联数组按值排序、也不处理多维或自定义规则,直接用容易丢数据或排错。
为什么 sort() 和 rsort() 只适合简单索引数组
这两个函数强制把数组转成数字索引,原键名(尤其是字符串键)一律丢弃。比如你有个配置数组:['host' => 'localhost', 'port' => 3306],一调用 sort() 就变成 [0 => 'localhost', 1 => 3306],后续用 $config['host'] 直接报错。
- 仅适用于纯数字索引、且你明确不需要保留键名的场景(如临时列表去重后排序)
-
rsort()是倒序版,行为完全一样,只是顺序相反 - 对字符串数组默认按字典序,对数字数组也当字符串比(
20 > 100成立),要数值比较得加SORT_NUMERIC标志
关联数组按值排序必须用 asort() / arsort()
保留键值对关系是关键。比如用户积分榜:['alice' => 87, 'bob' => 92, 'carol' => 76],想按分数升序排但还要知道谁对应多少分,就得用 asort():
asort($scores); // 结果:['carol'=>76, 'alice'=>87, 'bob'=>92],键还在
-
asort()升序,arsort()倒序 - 默认按字符串比较,数字大小写敏感;需要数值比较加
SORT_NUMERIC,字符串忽略大小写加SORT_STRING | SORT_FLAG_CASE - 如果键是中文或特殊字符,PHP 会按 UTF-8 字节序排,不是真正的 Unicode 排序,需用
uasort()配合collator_compare()
多维数组或复杂规则只能靠 usort() 和 uasort()
比如订单数组按发货时间排序:['order_id'=>123, 'ship_at'=>'2024-05-10'],sort() 完全无能为力。
-
usort($orders, fn($a, $b) => strtotime($a['ship_at']) strtotime($b['ship_at']))—— 注意必须返回整数(-1/0/1),用飞船操作符最安全 - 要保留原始键名(比如用订单号当键),改用
uasort() - 回调函数里别直接改
$a或$b的值,它们是副本;也不要依赖外部变量,PHP 7.4+ 推荐用匿名函数闭包捕获变量 - 性能上,
usort()比内置函数慢一截,万级数据要注意,可提前把要比较的字段提取成单独索引数组再用array_multisort()
array_multisort() 是隐藏高手,适合多字段+混合方向排序
比如先按状态(字符串)升序,状态相同时再按创建时间(时间戳)降序,usort() 写起来啰嗦,array_multisort() 更直白:
$statuses = array_column($items, 'status');<br>$times = array_column($items, 'created_at');<br>array_multisort($statuses, SORT_ASC, $times, SORT_DESC, $items);
- 它会对所有传入数组做相同位置的重排,所以
$items被动跟着变 - 每个排序数组可以独立指定方向(
SORT_ASC/SORT_DESC)和类型(SORT_NUMERIC等) - 不能直接用于关联数组的键排序,要排键得先用
array_keys()提取再映射回去 - 错误常见于列提取失败(比如某行缺
'status'字段),导致$statuses长度和$items不一致,整个排序结果错位
真正麻烦的从来不是“怎么排”,而是“排完键还在不在”“中文能不能正确比”“时间字符串要不要先转时间戳”——这些细节不盯住,线上就出数据错乱。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











