2.4. 基线

未匹配的标注

基线

PHPStan 处理和分析不同质量代码库的基本方式是通过 规则级别。它允许开发者在项目中即刻使用 PHPStan,当他们修复错误时,在更自信的类型安全 (type-safety) 中,代码的严谨性也随之增加。

通常把 PHPStan 引入持续集成(CI pipeline)的工作流是把级别 0 的报错数维持在 0,然后把代码合并到主分支。 当开发者满意时,可以尝试提高一个规则级别,继续检查错误并全部修复,然后开始享有更严谨的代码。

规则级别为我们提供了很好的服务,但也伴随一些注意事项:

  1. 升级到功能更强大的 PHPStan 新版本可能需要大量工作 —— 你需要修复所有新错误以保持和之前同等水准的分析结果。
  2. 当开发者以较宽松的规则级别做分析时,可能会错过一个真正的 bug。
  3. 引入并使用新的高级自定义规则之前,需要修复所有的违规行为。

这就是基线入场的时机。

PHPStan 允许你将当前报告的错误列表声明为基线,并使其在后续运行中不被报告。 这使你只需要注意新的和有修改的代码。
当你没有时间或精力解决几十几百个错误的时候,最适合用它了。如果有 15,000 个错误,它不会是最好的工具 —— 你可能应该花更多时间配置 PHPStan 或以较低的规则级别运行它。

生成基线

如果你想要把当前的错误列表作为基线导出,可以用 PHPStan 的 --generate-baseline

vendor/bin/phpstan analyse --level 7 \
  --configuration phpstan.neon \
  src/ tests/ --generate-baseline

它会生成带有每个文件错误数的列表,并保存为 phpstan-baseline.neon。你也可以在 --generate-baseline CLI 选项后指定另一个文件名。

基线文件示例如下:

parameters:
    ignoreErrors:
        -
            message: "#^Only numeric types are allowed in pre\\-decrement, bool\\|float\\|int\\|string\\|null given\\.$#"
            count: 1
            path: src/Analyser/Scope.php
        -
            message: "#^Anonymous function has an unused use \\$container\\.$#"
            count: 2
            path: src/Command/CommandHelper.php

然后,你应该把这个文件放在 配置文件:

includes:
    - phpstan-baseline.neon

parameters:
    # your usual configuration options

你下次运行 PHPStan 时,分析结果将忽略基线里的错误。你可以通过编辑基线文件来手动管理,或者通过运行 PHPStan 加 --generate-baseline 来重新生成整个文件。

如果某些被忽略的错误不再出现在结果中,PHPStan 会通知你,然后你必须从基线文件中移除该错误。你可以通过在配置中设置 reportUnmatchedIgnoredErrorsfalse 关闭此行为:

parameters:
    reportUnmatchedIgnoredErrors: false

用例

基线成功地解决了以上提及的所有问题。

立即升级到 PHPStan 的新版本

如果你使用 PHPStan 的古老版本分支,例如 0.10.x 甚至 0.9.x,这尤其方便。你可能推迟了想要尝试的升级,因为你被 PHPStan 数百个新错误吓到了。但是通过基线,你可以马上利用新规则。它们会用更挑剔的眼光分析你的代码,而老代码的问题静静地呆在基线里,等你心情好的时候再去解决。

即时有错误也以更高的级别进行分析

如果你在级别 2 上实现了零错误,首先恭喜你!级别 2 会检查:在变量上调用未知方法、验证 phpDocs 中的类型以及其他的问题。但是在你用级别 5 之前,它不会告诉你,你给一个方法传了错误的参数类型!

因此你错过了一个 bug,而它可能进入生产环境。

而依靠基线,你可以运行级别 5 的 PHPStan 并导出所有的错误。这样的效果就是你写的新代码会执行更严格的检查标准 —— 禁止任何新的bug进入生成环境。

引入自定义规则并将保持高水准的新代码

对抗技术债务的一个策略就是提出你想遵循的最佳实践,并且把它们逐步应用在你的代码库,尤其是你的新代码。

利用基线,你可以启用 phpstan-strict-rules 或者来自 ergebnis/phpstan-rules 拓展包的精确规则并把它们只应用于新代码。例如,如果你选择不再继承任何类(因为继承是邪恶的,而你应该使用组合),你可以启用这个规则但不需要处理现有的带父类的类。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~