usort 仅按值排序且重置键名为数字索引,回调函数必须返回整数(-1/0/1),不可用布尔值;字符串用 strcmp(),数值差需防溢出;多维数组中 $a/$b 是元素副本;相等元素顺序在 PHP 8.0+ 稳定但不保证;保留键名须用 uasort。

usort 不保留原数组键名,只按值排序,且必须用整数返回值控制顺序——这是它和 uasort、uksort 最根本的区别。
回调函数必须返回 int,不能靠布尔值或 float
常见错误是写成 return $a > $b;,这返回的是布尔值,PHP 会强制转成 0 或 1,导致所有“不相等”情况都视为“大于”,排序错乱。
- 正确写法:用三元表达式显式返回
-1、0、1,例如return ($a $b) ? 1 : 0); - 字符串比较优先用
strcmp()或strcasecmp(),它们本身返回标准整数,直接return strcmp($a, $b);就行 - 数值差值可直接用(仅限整数/浮点安全场景):
return $a['score'] - $b['score'];,但注意溢出或精度丢失风险
对多维数组或对象属性排序时,$a 和 $b 是元素副本,不是引用
比如你传入 $users = [['name' => 'Alice'], ['name' => 'Bob']],回调里 $a 就是 ['name' => 'Alice'] 这个数组,可直接取键访问。
- 访问字段:用
$a['age']、$a->id或isset($a['email']) ? $a['email'] : ''防止未定义索引警告 - 嵌套结构:如
$a['profile']['city'],建议先做存在性判断,避免 Notice - 类中调用需传数组形式回调:
usort($data, [$this, 'compareMethod']);,不能直接写'compareMethod'
相等元素的相对顺序在 PHP 8.0+ 是稳定的,但别依赖它
PHP 8.0 开始,usort 内部使用稳定排序算法,相同比较结果的元素会保持原有先后位置。但文档仍标注“相对顺序未定义”,因为:
立即学习“PHP免费学习笔记(深入)”;
- 这是实现细节,不是语言契约,未来版本可能调整
- 若回调逻辑本身没覆盖全部分支(比如漏写
==分支),实际行为就不可控 - 跨 PHP 版本部署时,低版本(如 7.4)仍可能打乱顺序
排序后原键名彻底丢失,要保留关联请改用 uasort
usort 总是重置为 0,1,2,... 数字索引,哪怕你传入的是 ['id_123' => [...], 'id_456' => [...]],返回数组也只剩数字键。
- 需要保留原始键名?必须换
uasort - 想按键名排序?该用
uksort - 调试时发现键没了,第一反应不是数据丢了,而是选错了函数
真正容易被忽略的,是回调函数签名和返回类型的隐式约束:哪怕你传的是字符串数组,usort 也要求回调严格返回 int;任何偏差都会让排序变成随机洗牌——而这种错误往往没有报错,只有结果不对。



















