Psalm —— PHP 静态代码质量检测工具

PHP

简介

在进入主题之前,我们先说明几件事。“Psalm”可能暗示着某种宗教的东西,但它只是一个工具名称,是 PHP Static Analysis Linting Machine 的缩写。 它面向 PHP 开发人员 — 由 Vimeo 的成员编写, 他们在5年前就已经意识到可以使用一种工具去帮助他们在代码发布到生产之前找到未发现的 bug 或者错误。

代码质量工具

任何改进我们代码的工具都可以归类为代码质量工具。在 BornFight,我们在使用 PHP 进行开发时使用了其中的几个:

  • PHPCSFixer — 编码标准定位器,用于在整个项目中执行单一编码标准
  • PHPCPD — 复制/粘贴检测器,用于检测重复代码
  • PHPMD — 混乱检测器,用于在干净代码、代码大小、命名等方面执行规则。
  • PHPStan — 静态分析工具,类似于 Psalm

读完列表中的最后一个项目后,你可能会问自己,为什么这篇文章谈论的是我们不使用的静态分析工具 Psalm (因为它不在列表中),而不是我们实际使用的类似工具 PHPStan。嗯,我亲爱的读者,我发现强迫自己研究一个主题的最好方法是写一篇帖子或为某人普及一下知识。更重要的是,如果该工具被证明是有用的,那么它可以是现有 CI 管道的一个很好的补充,甚至可能是 PHPStan 的替代品。 不管怎样,让我们更深入地研究一下。

静态… 什么?!

所以, “Static Analysis Linting Machine”? 这是一些很有说服力的话。静态分析显然意味着它分析一些东西,在本例中是我们的代码,但不执行它。单词“lint”在网上有多种定义,我找到的与软件无关的定义之一是“堆积在口袋或肚脐上的毛茸茸”。好吧,我觉得它对解释没有帮助,但是我还是会试着用它。在写代码的时候,我们应该尽量不犯错误。尽管如此,无论我们如何努力,随着时间的推移,在将其发布到生产之前, 代码库 (口袋) 积累未发现的错误 (沾着的毛茸茸的毛)。我们应该努力让我们的代码库和口袋都干净。

这就是“Psalm”的用武之地,帮助我们实现这样的目标 (至少对于代码库来说,我们仍然需要自己清理口袋。).

给我一些特征

在清理了关于 Psalm 和静态分析工具的一些问题之后,我们仍然在问自己,它发现了什么样的错误或可能的错误?嗯,尽管使用 PHP 进行开发可能会很愉快,但重要的是要了解它的利弊。因为它是一种解释语言,而不是编译语言,所以它不强制类型安全。

下面是一个工作代码的简单示例:

function doubleTheNumber($number) {
  return $number * 2;
}

$number = 5;
echo doubleTheNumber($number);

但是,它也可以用类型提示编写:

function doubleTheNumber(int $number): int {
  return $number * 2;
}

$number = 5;
echo doubleTheNumber($number);

第二种方法要安全得多,因为使用类型提示时,我们不允许将非整数值传递给函数,而且如果我们需要使用函数的返回值,我们可以确定它将是整数。

如果我们传递了一个空数组,运行 Psalm 会告诉我们类似以下内容:

ERROR: InvalidArgument - 8:22 - Argument 1 of doubleTheNumber expects int,
array<empty, empty> provided - https://psalm.dev/004

很酷,对吧? 类型检查是它最重要的特性。问题还包含到专用页面(在本例中为psalm.dev/004)的链接,以及它的解释和修复帮助那就是。 通过调查和解决错误,我们实际上是在学习如何编写更好的代码,以及 PHP 和一般编程中的一些不良做法。

如果您考虑将 Psalm 添加到现有的代码库,但是觉得它会抛出太多与类型相关的错误,那么也有一个解决方案。其中一个功能被称为Psalter(不,我们仍然不是在谈论任何宗教的东西)。它可以修复它发现的许多问题,比如添加丢失的类型提示,甚至删除一些死代码,比如未使用的变量或函数。

另一种情况可能是代码库太大,没有时间修复所有问题。但这并不意味着你应该继续编写有错误的代码。这就是基线的功能介入的地方-它允许你放弃所有发现的错误。它将所有错误存储在一个文件中,并且不再提及它们,但是它将显示在激活基线之后编写的新代码产生的每个新错误。

Alt Text

由于 Psalm 检查多种类型的错误,这取决于开发人员的知识和其他因素,因此处理所有这些错误可能是压倒性的。这就是级别严格派上用场的地方。有8个级别的严格,其中1级是最严格的。 级别越严格,包含的错误类型越多,反之亦然。

有时,需要将整个目录排除在分析之外,或者只需要排除特定方法上的特定类型错误。这可以通过屏蔽配置文件内的错误或通过文档块来实现。

下面是后者的一个示例:

class Foo {
    private string $bar = 'bar';

    public function getBar() : string {
        return $this->bar;
    }
}

$a = new Foo();
/** @psalm-suppress UnusedMethodCall */
$a->getBar();

任何级别的严格通常都会抛出如下内容:

ERROR: UnusedMethodCall - 12:5 - The call to Foo::getBar is not used

但只要它被屏蔽,就不会被提及。

由于 Psalm 支持大量文档块注释,为了最大限度地利用 Psalm 的类型检查特性,使用它们非常重要。它甚至有自己的注释,称为模板注释和断言注释。到目前为止,通过研究,我觉得它们是这个工具的重要组成部分,也许在我更多地测试他们之后,它们值得有自己的博客文章。

结论

目前,使用非类型化代码可能是可行的,但作为开发人员意味着要始终超前思考。在这样的代码库中编写任何新代码都会更加紧张和可怕,特别是对于项目中的新开发人员而言。随着代码库变得越来越大,以及更频繁地弹出不可预测的错误,引入静态分析工具(如 Psalm)对解决这些问题非常有帮助。

此外,通过处理代码库中的 Psalm 问题和警告,开发人员学习如何编写更好和可维护的代码,这是每个开发人员都应该努力实现的。别忘了,错误越少,客户就越高兴,这在商业中的重要性不言而喻!

如果这篇文章对你有用,并且你想知道更多关于 Psalm 的事情,请让我知道。在进行了更多的 Psalm 练习之后,我想我可以写一些关于它更深入的用法,或者将它与 PHPStan 进行比较,看看它会走向何方。

你呢?

你对这个问题有什么看法? 如果你有使用 Psalm 或任何其他静态分析工具的经验,我将很高兴听到你对此的意见,所以请在下面自由发表评论 :)

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://dev.to/bornfightcompany/how-to-i...

译文地址:https://learnku.com/php/t/49686

本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!