PHP8.0.0中发生了什么事打破了usort(…(int)(strlen($a)<;strlen($b));?

PHP8.0.0中发生了什么事打破了usort(…(int)(strlen($a)<;strlen($b));?,php,usort,php-8,Php,Usort,Php 8,代码 我不知道是什么内部变化导致了这种差异,但您的排序回调有点古怪。仅当$a和$b在功能上“相等”(在本例中,如果它们具有相同的字符串长度)时,才应返回0。否则,如果$a在$b之前排序,则返回1,否则返回-1。如果我适当地调整您的回调,就会得到预期的输出 usort($consts,function($a,$b){ $aLen=strlen($a); $bLen=strlen($b); 如果($aLen==$bLen){ 返回0; } 返回$aLen

代码


我不知道是什么内部变化导致了这种差异,但您的排序回调有点古怪。仅当$a和$b在功能上“相等”(在本例中,如果它们具有相同的字符串长度)时,才应返回0。否则,如果$a在$b之前排序,则返回1,否则返回-1。如果我适当地调整您的回调,就会得到预期的输出

usort($consts,function($a,$b){
$aLen=strlen($a);
$bLen=strlen($b);
如果($aLen==$bLen){
返回0;
}
返回$aLen<$bLen?1:-1;
});

3v4l:

这是因为您返回的是0或1,而不是-1。 您应该改用spaceship操作符:

usort($consts,function($a,$b){
返回strlen($b)strlen($a);
});

如果双方相等,则应返回0。

这里的大多数其他答案都集中在如何解决问题上,但我想我会尝试解释为什么在PHP8中会发生这种变化,我想这正是您感兴趣的

PHP8引入了,这(听起来)意味着PHP中的所有排序函数现在都是“稳定的”。更多详细信息请访问链接

其他答案已经很好地说明了这一点,但是您的函数返回零或大于零的数字。以前的PHP排序实现(所有低于8的版本)都认为零和负数是相同的;正如上面提到的RFC,检查只是针对大于零或不大于零的数字。返回零意味着这些元素的处理方式与
$a<$b
相同

PHP引入了一个弃用警告,因此许多返回布尔值的排序实现仍然可以工作。RFC给出了更多的细节,但重要的是它意味着PHP8仍然向后兼容(因此这是一个弃用通知,而不是警告)。这里的边缘情况是,虽然函数有效地返回一个布尔值-0表示相同的长度,1表示
$a<$b
-因为您将其转换为整数,但PHP8中的向后兼容性检查不会捕获它,因此所有“相等”元素都被视为
$a

比较:

function($a, $b) { return (int) (strlen($a) < strlen($b)); }
function($a,$b){return(int)(strlen($a)
如问题所述-在PHP中正确工作
9: E_WARNING
21: FILTER_FLAG_STRIP_LOW
7: E_ERROR
26: FILTER_FLAG_STRIP_BACKTICK
usort($consts, function($a, $b) {
    return strlen($b) <=> strlen($a);
});
function($a, $b) { return (int) (strlen($a) < strlen($b)); }
function($a, $b) { return strlen($a) < strlen($b); }
function($a, $b) { return strlen($b) <=> strlen($a); }