PHPStan 错误标识符 div.rightNonNumeric 详解:除法运算符右操作数不是数值类型
2026/9/23 5:26:13 网站建设 项目流程

PHPStan 错误标识符 div.rightNonNumeric 详解:除法运算符右操作数不是数值类型

【免费下载链接】phpstanPHP Static Analysis Tool - discover bugs in your code without running it!项目地址: https://gitcode.com/gh_mirrors/ph/phpstan

导读

div.rightNonNumeric是 PHPStan 在启用 phpstan-strict-rules 为骨架,结合 errorsIdentifiers.json 中的规则映射与同族文档,完整讲解该错误的触发条件、PHP 语言语义依据、两种修复思路,以及与之配套的同类算术运算检查(+-*%**)。读完你将对 strict-rules 的"运算数必须是数值"系列规则形成系统认识,并能直接在自己的项目里复现、修复并配置该检查。

错误标识符是什么:一条错误的前缀编号

在 PHPStan 2.x 中,每条错误都可以携带一个机器可读的错误标识符,格式类似div.rightNonNumeric。其中:

  • div表示该错误与除法(division)运算相关;
  • rightNonNumeric表示问题是"右侧操作数不是数值类型";
  • 与之对应,div.leftNonNumeric.md 负责描述"左侧操作数不是数值类型"的情形。

该文档文件的 frontmatter 记录了它的元信息:

title: "div.rightNonNumeric" shortDescription: "Right side of the division operator is not a numeric type." ignorable: true

ignorable: true表示该错误可以在配置中通过ignoreErrors或基线(baseline)机制显式忽略,与那些->nonIgnorable()的强制错误不同。

触发示例:一段会被报告的代码

文档给出了一个最小化的、必然触发该错误标识符的 PHP 示例:

<?php declare(strict_types = 1); function doFoo(int $numerator, bool $flag): void { $result = $numerator / $flag; }

注意示例开头固定使用declare(strict_types = 1);——这是 strict-rules 类检查的典型测试环境,因为非严格模式下 PHP 的弱类型转换会掩盖部分问题。这里$numeratorint,而除号右侧的$flagboolbool不属于数值类型,因此 PHPStan 会报告div.rightNonNumeric

为什么会报告这个错误:规则来源与 PHP 语义

规则来源:phpstan-strict-rules

该错误并非 PHPStan 核心自带,而是由phpstan/phpstan-strict-rules包提供。从本仓库的 errorsIdentifiers.json 可以看到明确的标识符到规则的映射:

"div.leftNonNumeric": → PHPStan\Rules\Operators\OperandsInArithmeticDivisionRule (line 51) "div.rightNonNumeric": → PHPStan\Rules\Operators\OperandsInArithmeticDivisionRule (line 59)

也就是说,div.leftNonNumericdiv.rightNonNumeric都由同一个规则类OperandsInArithmeticDivisionRule报告,只是分别覆盖操作符的左侧(源码第 51 行附近)与右侧(源码第 59 行附近)的检查逻辑。该规则类位于 phpstan-strict-rules 包的src/Rules/Operators/目录下。

要在项目中使用这条规则,需要安装并启用 strict-rules,典型的做法是:

composer require --dev phpstan/phpstan-strict-rules

然后在phpstan.neon中包含其规则文件:

includes: - vendor/phpstan/phpstan-strict-rules/rules.neon

启用后,OperandsInArithmeticDivisionRule会对每个除法表达式做操作数类型检查,一旦发现非数值类型就会报告上述标识符。

PHP 语义依据:除法要求数值操作数

从 PHP 语言语义看,除法运算符/期望两个操作数都是数值类型(intfloat)。当右侧操作数是boolnullarrayobject等非数值类型时:

  • 在非严格模式下,PHP 可能尝试进行弱类型转换,产生不符合预期的结果
  • 在严格模式(declare(strict_types = 1))下,则可能直接抛出TypeError

即便某些情况下bool能被运行时"凑合"转换成数字(如true转 1、false转 0),代码的意图也几乎肯定是错误的——把布尔值放进除法运算,通常是参数类型设计错误或变量使用错误,这正是 strict-rules 要在静态分析阶段拦截它的原因:指向"会导致崩溃、根本不会按预期执行、或与开发者意图不符"的代码。

如何修复:两种由文档给出的标准方案

方案一:修正类型声明,让右操作数真正是数值

最直接的修复是修复 bug 本身——把参数类型从bool改为数值类型:

<?php declare(strict_types = 1); -function doFoo(int $numerator, bool $flag): void +function doFoo(int $numerator, float $divisor): void { - $result = $numerator / $flag; + $result = $numerator / $divisor; }

方案二:在使用前显式转换类型

如果业务上确实需要传入一个布尔值参与运算(这种情况应当非常罕见),则在除法之前显式转换,让类型信息与运行时行为保持一致:

<?php declare(strict_types = 1); function doFoo(int $numerator, bool $flag): void { - $result = $numerator / $flag; + $result = $numerator / (int) $flag; }

注意这里使用的是显式强转(int),而不是依赖 PHP 的隐式弱类型转换——显式转换表达了开发者的真实意图,也让 PHPStan 能推导出/右侧现在是int,从而消除该错误。

修复顺序的通用建议

从本仓库 website/errors/CLAUDE.md 对错误文档写作规范的约定来看,推荐按以下优先级修复这类错误:

  1. 修复实际 bug(把参数类型改对);
  2. 使用原生 PHP 类型声明收窄类型;
  3. 使用 PHPDoc 类型(@param@return@var)收窄类型;
  4. 在函数体内进行类型收窄;
  5. 如果规则可配置,再考虑调整 PHPStan 配置。

div.rightNonNumeric而言,前两条即"改参数类型 / 显式强转"通常已足够。

同类检查:一套完整的"运算数必须为数值"规则家族

div.rightNonNumeric并不是孤例。在 website/errors 目录下,可以找到一整套结构完全相同的姊妹文档,它们共同构成 strict-rules 的"算术运算数数值性"检查家族:

运算符左侧检查右侧检查
除法/div.leftNonNumeric.mddiv.rightNonNumeric(本文)
取模%mod.leftNonNumeric.mdmod.rightNonNumeric
加法+plus.leftNonNumericplus.rightNonNumeric
减法-minus.leftNonNumericminus.rightNonNumeric
乘法*mul.leftNonNumericmul.rightNonNumeric
幂运算**pow.leftNonNumericpow.rightNonNumeric

例如 mod.leftNonNumeric.md 明确写到:"只有intfloat类型应当用于算术运算",这与本文档的核心结论完全一致。当你为%+-***的某个操作数传入了boolnullarrayobject等类型时,PHPStan 同样会报告对应的*NonNumeric标识符,修复思路与本文完全相同:改对类型,或者在使用前显式转换。

如何在你的项目中使用错误标识符

错误标识符的价值在于:你可以不依赖错误消息文本,而是通过稳定的标识符来精确配置忽略规则。例如在phpstan.neon中只忽略特定位置的div.rightNonNumeric,而保留其它位置的同类错误:

parameters: ignoreErrors: - identifier: div.rightNonNumeric path: legacy/legacy_calculation.php

也可以把div.rightNonNumeric等标识符整体加入基线(baseline),方便团队逐步清理存量代码。由于该标识符ignorable: true,所有上述忽略方式都受支持。

小结

  • div.rightNonNumericphpstan/phpstan-strict-rulesOperandsInArithmeticDivisionRule规则报告,用于捕获除法右操作数非数值(boolnullarrayobject等)的代码;
  • 这类代码在运行时可能产生意外结果,严格模式下甚至抛出TypeError,属于"基本可以确定是逻辑错误"的高置信度警告;
  • 标准修复方式是修正类型声明使用前显式强转(如(int));
  • 它属于 strict-rules 覆盖+-*/%**六个运算符的*NonNumeric规则家族,左侧/右侧各有一个对应标识符,可参考 div.leftNonNumeric.md 等姊妹文档交叉查阅;
  • 通过identifier: div.rightNonNumeric可以在ignoreErrors或基线中精确配置忽略范围。

想让代码库中的算术运算更健壮,直接启用phpstan/phpstan-strict-rules即可,这一族规则会自动开始工作,把"拿布尔值做除法"这类隐性 bug 拦截在运行之前。

【免费下载链接】phpstanPHP Static Analysis Tool - discover bugs in your code without running it!项目地址: https://gitcode.com/gh_mirrors/ph/phpstan

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询