Composer在线学习地址:学习地址
最近,我们团队计划将一个运行多年的老项目从 php 7 升级到 php 8。起初,我们信心满满,认为只要处理好一些明显的语法变动和废弃功能,升级就会一帆风顺。然而,很快我们就遇到了一个让人头疼的“隐形杀手”:php 8 对字符串和数字的比较逻辑进行了调整。
在 PHP 7 中,如果你将一个非空字符串与整数
0
==
'banana' == 0
true
false
<pre class="brush:php;toolbar:false;">$a = 'banana'; $b = 0; if ($a == $b) { echo 'PHP 7 会显示这个'; // PHP 7 Output } else { echo 'PHP 8 会显示这个'; // PHP 8 Output }
想象一下,在数万行的代码中,可能散落着无数这种看似无害但实际上行为已改变的比较。如果这些比较恰好处于关键的业务逻辑中,例如权限判断、数据过滤或者条件分支,那么升级后,我们的程序就会在不知不觉中产生错误,而且这种错误很难通过常规测试发现,因为它们可能只在特定数据或特定场景下触发。手动去查找和修改这些地方,简直是一场噩梦,耗时耗力,还容易遗漏。
orklah/psalm-insane-comparison
正当我们为如何有效地检测和修复这些潜在问题而焦头烂额时,我们发现了
orklah/psalm-insane-comparison
它的工作原理很简单:
立即学习“PHP免费学习笔记(深入)”;
<pre class="brush:php;toolbar:false;">composer require --dev orklah/psalm-insane-comparison
<pre class="brush:php;toolbar:false;">vendor/bin/psalm-plugin enable orklah/psalm-insane-comparison
<pre class="brush:php;toolbar:false;">vendor/bin/psalm
这个插件会在 Psalm 分析代码时,自动识别出所有可能受 PHP 8 比较规则影响的代码行,并给出警告。这样一来,我们就不必大海捞针,而是能够精准地定位到所有需要修改的地方。
orklah/psalm-insane-comparison
===
当
orklah/psalm-insane-comparison
使用严格相等比较(===
<pre class="brush:php;toolbar:false;">$a = 'banana'; $b = 0; if ($a === $b) { // 这将永远不会被执行,PHP 7 和 PHP 8 行为一致 echo '这不可能'; } else { echo 'PHP 7 和 PHP 8 都会显示这个'; }
显式类型转换: 如果你确实需要进行类型转换,请明确地进行。
<pre class="brush:php;toolbar:false;">// 将字符串转换为整数再比较 $a = 'banana'; $b = 0; if ((int)$a == $b) { // (int)'banana' 会变成 0,所以这里会是 true echo 'PHP 7 和 PHP 8 都会显示这个'; } else { echo '这不可能'; } // 将整数转换为字符串再比较 $a = 'banana'; $b = 0; if ($a == (string)$b) { // 'banana' == '0' 结果是 false echo '这不可能'; } else { echo 'PHP 7 和 PHP 8 都会显示这个'; }
使用 Psalm 类型注解: 如果你的变量类型是明确的,可以使用 Psalm 的类型注解来帮助其理解,从而消除误报。
<pre class="brush:php;toolbar:false;">// 明确 $b 是 positive-int $a = 'banana'; /** @var positive-int $b */ $b = 1; // 假设 $b 不会是 0 if ($a == $b) { // Psalm 会理解 'banana' == 1 永远是 false echo '这不可能'; } else { echo 'PHP 7 和 PHP 8 都会显示这个'; } // 明确 $a 是 numeric-string /** @var numeric-string $a */ $a = '123'; // 假设 $a 是数字字符串 $b = 0; if ($a == $b) { // 行为取决于 $a 的值,但 Psalm 不会再警告 'banana' == 0 的情况 echo 'PHP 7 和 PHP 8 的行为取决于 $a 的值'; } else { echo 'PHP 7 和 PHP 8 的行为取决于 $a 的值'; }
orklah/psalm-insane-comparison
以上就是如何解决PHP8字符串与数字比较的陷阱,使用Psalm插件确保代码平稳升级的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号