← PHP array_reverse()函数:反转数组元素顺序的实战教程 没有下一篇了 →

PHP rsort()函数:数组降序排序的实战教程

著
原创 2026-10-08 PHP 已有人查阅

一、rsort()的定位

PHP的排序函数按两个维度分类:按值还是按键,升序还是降序。rsort()属于"按值降序"这一类。

它的名字可以拆开理解:r表示reverse(降序),sort表示按值排序。和它对应的是sort()(按值升序)。按键排序的那一组则是ksort()和krsort()。

用之前要明确一点:rsort()会破坏键值对应关系。排序后数字键重新从0开始编号,字符串键直接丢失,只保留值。这个特性决定了它适合"列表类"数据,不适合"映射类"数据。

二、函数原型与参数

rsort(array &$array, int $sort_flags = SORT_REGULAR): bool
参数 说明 是否必需
array 待排序的数组,以引用传入 必需
sort_flags 排序标志,指定比较方式 可选

返回值:成功返回true,失败返回false。

参数是引用传递,函数直接修改原数组,不返回排序后的数组。这一点和array_reverse()不同,后者返回新数组。写代码时如果$result=rsort($arr),$result拿到的是true/false,不是数组。这是新手常犯的错误。

三、sort_flags排序标志

标志 含义
SORT_REGULAR 默认,按常规方式比较,不转换类型
SORT_NUMERIC 按数值比较
SORT_STRING 按字符串比较
SORT_LOCALE_STRING 按本地化字符串比较
SORT_NATURAL 自然排序,如"img10"排在"img2"之后
SORT_FLAG_CASE 可与SORT_STRING组合,忽略大小写

默认的SORT_REGULAR会按PHP的类型比较规则来,数字和数字比大小,字符串和字符串比字典序。混合类型时结果可能不符合直觉,这时候需要显式指定标志。

四、基本用法

数字数组降序:

<?php
$numbers = array(400, 600, 100, 220, 110);
rsort($numbers);
print_r($numbers);

输出:

Array
(
    [0] => 600
    [1] => 400
    [2] => 220
    [3] => 110
    [4] => 100
)

键名被重新编号为0到4,值和顺序都符合预期。

字符串数组降序:

<?php
$cars = array("hexa", "nexon", "audi");
rsort($cars, SORT_REGULAR);
print_r($cars);

输出:

Array
(
    [0] => nexon
    [1] => hexa
    [2] => audi
)

按字典序从大到小,n排在h前面,h排在a前面。

五、关联数组的键会丢失

这是rsort()使用中最需要留意的地方:

<?php
$fruit = array("d" => "mango", "a" => "orange", "b" => "banana");
rsort($fruit);
print_r($fruit);

输出:

Array
(
    [0] => orange
    [1] => mango
    [2] => banana
)

原本的键d、a、b全部消失,值按降序重新排列,键变成0、1、2。如果业务上需要保留"哪个键对应哪个值",rsort()会把这个信息破坏掉。

需要保留键值对应关系时,应该用arsort()(按值降序,保留键)或krsort()(按键降序,保留键)。这三个函数的区别如下:

函数 排序依据 方向 键名
sort() 值 升序 重新编号
rsort() 值 降序 重新编号
asort() 值 升序 保留
arsort() 值 降序 保留
ksort() 键 升序 保留
krsort() 键 降序 保留

个人经验:做过一个商品销量排行榜,数据是['商品ID'=>销量]的关联数组。一开始用rsort()排序,排完销量顺序对了,但商品ID全没了,前端拿不到该展示哪个商品。换成arsort()后,销量降序排列,商品ID依然挂在对应的销量上。需要"排序后还知道这条数据是谁"的场景,一律用arsort(),不要用rsort()。

六、混合类型数组的排序

数组里同时有数字和数字字符串时,SORT_REGULAR的比较结果可能和预期不同:

<?php
$mixed = array("10", 9, "100", 20);
rsort($mixed, SORT_REGULAR);
print_r($mixed);

SORT_REGULAR下,PHP会把数字字符串按数值比较,结果通常是100、20、10、9的降序。但如果数组里混入了非数字字符串,比较规则会变,结果可能不稳定。处理混合类型数据时,显式指定SORT_NUMERIC或SORT_STRING,比依赖默认行为更可靠。

另一个常见坑是版本差异。PHP8之前和之后,字符串与数字的比较规则有过调整,同一段代码在不同版本下排序结果可能不同。项目里如果对排序顺序有严格要求,指定明确的sort_flags是稳妥的做法。

七、项目实例

实例一:成绩降序排名

<?php
$scores = array(88, 95, 72, 91, 85);
rsort($scores);
print_r($scores);

输出:

Array
(
    [0] => 95
    [1] => 91
    [2] => 88
    [3] => 85
    [4] => 72
)

纯数值列表排序,不需要保留原下标,rsort()直接可用。

实例二:保留商品ID的销量排行

<?php
$sales = array(
    'p101' => 320,
    'p102' => 580,
    'p103' => 210,
);

arsort($sales);
print_r($sales);

输出:

Array
(
    [p102] => 580
    [p101] => 320
    [p103] => 210
)

这里用的是arsort()而不是rsort()。原因就是商品ID必须保留,否则排序结果无法对应到具体商品。这是本节最值得记住的一个取舍点。

实例三:文件名自然降序

<?php
$files = array("img2.jpg", "img10.jpg", "img1.jpg");
rsort($files, SORT_NATURAL);
print_r($files);

输出:

Array
(
    [0] => img10.jpg
    [1] => img2.jpg
    [2] => img1.jpg
)

用SORT_NATURAL时,img10会排在img2前面(因为10大于2)。如果不用这个标志,按字符串比较,img2会排在img10前面,因为字符"2"大于"1"。处理带数字的文件名、版本号时,SORT_NATURAL更符合人的阅读习惯。

八、踩坑记录

坑一:把rsort()的返回值当数组用。rsort()返回bool,排序结果在原数组里。$sorted=rsort($arr)这种写法拿不到数组。

坑二:对关联数组用rsort()丢键。需要保留键值对应关系时,用arsort()而不是rsort()。

坑三:混合类型不指定sort_flags。默认的SORT_REGULAR在混合类型下比较规则复杂,结果不稳定。明确数据类型后指定SORT_NUMERIC或SORT_STRING。

坑四:以为排序是稳定的。PHP8.0之前,排序不保证相等元素的相对顺序。PHP8.0起排序变为稳定排序,但依赖这个特性前应确认运行环境的版本。

坑五:数值字符串比较。表单提交的数值是字符串类型,用SORT_REGULAR可能按字符串比较,出现"100"排在"20"前面的情况。数值排序应显式传SORT_NUMERIC。

坑六:rsort()和array_reverse()混用。想让有序数组倒过来,用array_reverse();想对无序数组降序排列,用rsort()。前者是反转顺序,后者是按值排序,语义不同。

九、本节课程知识要点

  1. rsort()按值降序排序,直接修改原数组,返回bool。

  2. 排序后数字键重新编号,字符串键丢失,这是它的固有行为。

  3. 需要保留键值对应关系时,用arsort(),不要用rsort()。

  4. sort_flags控制比较方式,混合类型数据应显式指定。

  5. 带数字的文件名、版本号排序,用SORT_NATURAL更符合阅读习惯。

  6. rsort()是排序,array_reverse()是反转顺序,两者用途不同。

十、常见问题

问:rsort()会返回排序后的数组吗?

不会。它返回true或false,排序结果直接写回传入的数组变量。

问:rsort()和arsort()有什么区别?

rsort()排序后键名重新编号,字符串键丢失;arsort()按值降序排序但保留原有的键值对应关系。

问:字符串数组排序能忽略大小写吗?

可以。传SORT_STRING|SORT_FLAG_CASE,这样大写和小写字母会被视为相同再排序。

问:排序后相等元素的顺序会变吗?

PHP8.0起排序是稳定的,相等元素保持原有相对顺序。更早的版本不保证这一点。

问:能不能只排序数组的一部分?

rsort()作用于整个数组。局部排序需要先array_slice()截取,排序后再拼回原数组。

← PHP array_reverse()函数:反转数组元素顺序的实战教程 没有下一篇了 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号