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

编码

<?php
$consts = get_defined_constants();
$consts = array_keys($consts);
usort($consts,function($a,$b){return (int)(strlen($a)<strlen($b));});
foreach($consts as $const){
    echo strlen($const).": ".$const."n";
}

将在 PHP 8.0.0 之前按照我的预期从最长到最短打印所有定义的常量。7.3.13 开始于

62: SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE
62: SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE
60: SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE
60: SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_SENSITIVE
51: SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX

但我不知道 PHP8.0.0 做了什么,它的输出开始于:

9: E_WARNING
21: FILTER_FLAG_STRIP_LOW
7: E_ERROR
26: FILTER_FLAG_STRIP_BACKTICK

你可以在 3v4l 上看到它:https ://3v4l.org/MP2IF

那么在 PHP 8.0.0 中发生了什么来破坏这段代码呢?

回答

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

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

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

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

相比:

function($a, $b) { return (int) (strlen($a) < strlen($b)); }

与问题一样 - 在 PHP <8 中正常工作,但不会引起弃用通​​知。https://3v4l.org/MP2IF


function($a, $b) { return strlen($a) < strlen($b); }

返回一个布尔值,因此 PHP 8 中的向后兼容性检查工作正常。但是现在提出了弃用通知。https://3v4l.org/fWR2Y


function($a, $b) { return strlen($b) <=> strlen($a); }

“正确”的解决方案,在所有版本中都能正常工作(至少自从引入了飞船操作员以来)。https://3v4l.org/6XRYW


以上是PHP8.0.0中发生了什么来破坏usort(…(int)(strlen($a)&lt;strlen($b)));?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>