在php项目里,我们经常会遇到要把一个数组里的元素按照值的大小重新排列的情况。如果数组里是数字或者字符串,直接用php内置的排序函数就能解决,但当排序规则比较特殊时,就需要用到usort配合自己写的比较逻辑来完成循环比较和排列。

为什么用usort而不是手写循环
手写for循环来回比较和交换值不仅代码多,还容易写错边界条件。usort是php提供的对数组值排序的函数,它会在内部循环调用我们给的比较函数,根据比较函数返回的正负来决定两个值谁大谁小,最终完成排序。这样我们只关心比较规则,不关心排序过程。
usort自定义比较法基础用法
usort的函数签名是usort(数组, 比较函数)。比较函数接收两个参数a和b,如果a小于b返回负数,等于返回0,大于返回正数,结果就是升序;反过来写就是降序。
<?php
$nums = array(5, 2, 9, 1, 7);
// 自定义比较函数,升序排列
function cmp($a, $b) {
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
usort($nums, 'cmp');
// 循环输出排列后的值
foreach ($nums as $val) {
echo $val . ' ';
}
// 输出:1 2 5 7 9
?>
对多维数组按某个字段值排序
实际开发中更常见的是数组里放的是关联数组,比如用户列表,要按年龄大小排。用usort同样很简单。
<?php
$users = array(
array('name' => '张三', 'age' => 28),
array('name' => '李四', 'age' => 19),
array('name' => '王五', 'age' => 35)
);
// 按age字段升序
usort($users, function($a, $b) {
if ($a['age'] == $b['age']) {
return 0;
}
return ($a['age'] < $b['age']) ? -1 : 1;
});
foreach ($users as $u) {
echo $u['name'] . ':' . $u['age'] . "n";
}
?>
降序与常用注意点
如果要把值从大到小排,只要把比较函数里的返回反过来,或者用<strong>spaceship运算符</strong>更简洁:
<?php
$nums = array(5, 2, 9, 1, 7);
// 降序
usort($nums, function($a, $b) {
return $b <=> $a;
});
print_r($nums);
?>
- usort会直接修改原数组,不会返回新数组。
- 比较函数里不要做太耗时的操作,否则大数据量时排序会变慢。
- 如果比较逻辑复杂,建议单独写成函数方便复用。
善用usort自定义比较法,可以让php数组按值大小排列的代码既短又清楚,不必再手写繁琐的循环交换。