You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP 8中usort排序结果异常:是Bug还是代码需调整?

PHP8中usort排序异常问题解析

问题场景

我编写了一段代码,意图将数组中的'BMW'排序至首位:

$cars=['Toyota','Volvo','BMW'];
usort($cars,function($v){return $v <=> 'BMW';});
var_export($cars);

不同版本结果差异

  • PHP7及更低版本结果符合预期:
array ( 0 => 'BMW', 1 => 'Volvo', 2 => 'Toyota', )
  • PHP8中的结果不符合预期:
array (0 => 'Volvo', 1 => 'BMW', 2 => 'Toyota',)

排查过程

经确认,问题并非出自太空船运算符(<=>),该运算符表现正常:

var_dump(
    'Volvo' <=> 'BMW',
    'BMW' <=> 'Volvo',
    'BMW' <=> 'Toyota',
    'Toyota' <=> 'BMW',
    'BMW' <=> 'BMW'
);

问题本质及解决方案

这不是PHP8的Bug,而是PHP8对usort回调函数的参数要求变得严格了。

usort的回调函数必须接收两个参数(待比较的两个元素$a和$b),通过返回值定义二者的排序关系:

  • 返回负数:$a排在$b前面
  • 返回正数:$a排在$b后面
  • 返回0:二者顺序不变

在PHP7及更早版本中,即使回调只定义了一个参数,PHP会自动补全第二个参数为null,勉强让排序逻辑“工作”;但PHP8开始严格执行回调参数的合规性,单参数的回调会导致排序算法无法正确比较元素对,最终出现不符合预期的排序结果。

修正后的代码

要实现将'BMW'排到首位的需求,正确的回调写法应该是:

$cars=['Toyota','Volvo','BMW'];
usort($cars, function($a, $b) {
    // 优先将BMW放到前面
    if ($a === 'BMW') return -1;
    if ($b === 'BMW') return 1;
    // 其他元素按常规字符串排序
    return $a <=> $b;
});
var_export($cars);

或者用更简洁的箭头函数写法(PHP7.4+支持):

$cars=['Toyota','Volvo','BMW'];
usort($cars, fn($a, $b) => ($a === 'BMW' ? -1 : ($b === 'BMW' ? 1 : $a <=> $b)));
var_export($cars);

运行修正后的代码,在PHP7和PHP8中都能得到预期结果:

array ( 0 => 'BMW', 1 => 'Toyota', 2 => 'Volvo', )

内容的提问来源于stack exchange,提问作者jspit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 17:30:56