作者:xhl583337984 | 来源:互联网 | 2024-12-05 13:25
在编写 PHP 脚本时,我们经常需要对数组进行自定义排序。下面是一个使用 usort
函数按字符串长度排序的例子:
$cOnsts= get_defined_constants();
$cOnsts= array_keys($consts);
usort($consts, function($a, $b) {
return (int)(strlen($a) });
foreach ($consts as $const) {
echo strlen($const) . ": " . $const . "\n";
}
这段代码在 PHP 8.0.0 之前的版本中能够按照预期从最长到最短打印出所有已定义的常量。例如,在 PHP 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
然而,在升级到 PHP 8.0.0 后,同样的代码产生了不同的排序结果,输出开始于:
9: E_WARNING
21: FILTER_FLAG_STRIP_LOW
7: E_ERROR
26: FILTER_FLAG_STRIP_BACKTICK
这种变化的原因在于 PHP 8.0.0 实现了稳定排序算法,这一改变通过 RFC 提案得以实施。稳定排序确保了当两个元素被视为相等时,它们在排序后的数组中的相对位置保持不变。这意味着如果排序函数返回 0,表示两个元素相等,它们的原始顺序将被保留。
在您的代码中,(int)(strlen($a) 这个表达式在 $a
和 $b
长度相等时总是返回 0,这导致 PHP 8.0.0 将这些元素视为相等,从而改变了它们的排序顺序。为了使代码在 PHP 8.0.0 及更高版本中也能正常工作,您可以考虑使用三元运算符或直接返回布尔值来避免这个问题:
function($a, $b) { return strlen($a) - strlen($b); }
或者使用 PHP 7.0 引入的宇航员操作符(spaceship operator):
function($a, $b) { return strlen($b) <=> strlen($a); }
这两种方法都可以确保在 PHP 8.0.0 及更高版本中正确地进行字符串长度的比较排序。