在 Laravel 中使用 PHP Codesniffer
发布于 作者: Paul Redmond
从 Laravel 9 开始,优秀的 Laravel Pint 已经包含在新的 Laravel 安装中。我喜欢 Pint,对大多数人来说,使用它进行所有代码风格格式化已经足够了。在 Laravel Pint 出现之前,我更喜欢使用 PHP CS Fixer 和 PHP Codesniffer 的组合——两者协同工作非常出色,并提供独特的规则,可以帮助强制执行代码风格。
行长风格是 PHP Codesniffer 可以补充 PHP CS Fixer 等工具的一个示例,我们可以使用两者来帮助开发人员坚持一致的代码风格。如果您使用的是 PSR-12,Lines 部分包含以下有关行长的信息
行长不得硬性限制。
行长软性限制必须为 120 个字符。
行长不应超过 80 个字符;长于此的行应拆分为多个后续行,每行不超过 80 个字符。
我们的 CI 工具可以强制执行行长的软性限制和硬性限制,但我对 PSR-12 的解释是,PHP Codesniffer 应该在遇到 > 80
行长时向我们发出警告,而不是返回任何错误。我们将在本文后面详细介绍这一点。
让我们一起在新的 Laravel 项目中设置 PHP Codesniffer,然后在后续教程中,我们将学习如何创建自定义的 PHP Codesniffer 标准,以便可以在所有项目中共享。
在此过程中,我将向您展示我喜欢设置的一些配置设置,以便在开发过程中最大限度地利用 PHP Codesniffer。
设置
我们要做的第一件事是创建一个示例项目,这样您就可以看到如何从头开始在 Laravel 中集成 PHP Codesniffer。
laravel new phpcs-part-1 --gitcd phpcs-part-1
git 标志将安装新的 Laravel 应用程序,初始化 git,并将所有内容提交到版本控制。这让我们得到一个干净的起点,可以查看我们在本教程中进行的更改。
接下来,让我们将 PHP Codesniffer 作为开发依赖项安装。
composer require --dev squizlabs/php_codesniffer
注意:在撰写本文时,所需的命令安装版本 ^3.7
,但您的版本可能略有不同,这并不重要。
如果您从命令行运行 phpcs
,您会看到它要求您指定路径。
$ vendor/bin/phpcsERROR: You must supply at least one file or directory to process. Run "phpcs --help" for usage information
不用担心,我们将在下一步添加一个配置文件来指定 PHPCS 应该包含(和排除)哪些路径,但是如果您使用默认规则集(Pear)运行它,您将在默认的 Laravel 安装中得到一堆错误。
$ vendor/bin/phpcs -v appRegistering sniffs in the PEAR standard... DONE (28 sniffs registered).... FILE: /Users/paul/code/sandbox/phpcs-part-1/app/Providers/AppServiceProvider.php--------------------------------------------------------------------------------FOUND 2 ERRORS AFFECTING 2 LINES-------------------------------------------------------------------------------- 2 | ERROR | Missing file doc comment 7 | ERROR | Missing doc comment for class AppServiceProvider--------------------------------------------------------------------------------
如果您检查退出代码,您会看到错误导致 PHPCS 退出并返回非零代码。
$ echo $?2
我想明确一点:这些错误不是因为我们的代码格式错误(恰恰相反),而是因为我们使用的是默认的 PEAR 标准,而 Laravel 默认情况下不遵循该标准。
让我们看看如何使用不同的标准和创建一个配置文件。
探索命令行工具
在向项目中添加配置文件之前,让我们看看相同的配置在命令行中将如何显示。我们知道我们不想使用 PEAR 标准,所以首先让我们使用内置的 PSR-12 标准运行 PHPCS 命令。
vendor/bin/phpcs --standard=PSR12 app
如果您仔细观察输出,您会注意到 PHP Codesniffer 的 PSR12 标准希望修复一些连接字符串周围的空格。
FILE: /Users/paul/code/sandbox/phpcs-part-1/app/Console/Kernel.php----------------------------------------------------------------------FOUND 2 ERRORS AFFECTING 1 LINE---------------------------------------------------------------------- 28 | ERROR | [x] Expected at least 1 space before "."; 0 found 28 | ERROR | [x] Expected at least 1 space after "."; 0 found----------------------------------------------------------------------PHPCBF CAN FIX THE 2 MARKED SNIFF VIOLATIONS AUTOMATICALLY----------------------------------------------------------------------
x
表示我们可以使用 Codesniffer 附带的 phpcbf
bin 自动修复这些嗅探器(并非所有 PHP Codsniffer 嗅探器都可以自动修复)。我们将在下一节介绍这个内容。
首先,让我们了解一下我喜欢使用的其他一些命令标志。一旦您开始在开发和 CI 中使用 PHP Codesniffer,我发现嗅探器的完整名称并不明显。您可能需要调整该嗅探器,在特定行上忽略它,等等。
要始终在命令行中看到完整的嗅探器,您可以使用 -s' 标志
vendor/bin/phpcs -s --standard=PSR12 app
以下是使用完整嗅探器时输出的示例。
FILE: /Users/paul/code/sandbox/phpcs-part-1/app/Console/Kernel.php----------------------------------------------------------------------------------------------------------------FOUND 2 ERRORS AFFECTING 1 LINE---------------------------------------------------------------------------------------------------------------- 28 | ERROR | [x] Expected at least 1 space before "."; 0 found | | (PSR12.Operators.OperatorSpacing.NoSpaceBefore) 28 | ERROR | [x] Expected at least 1 space after "."; 0 found | | (PSR12.Operators.OperatorSpacing.NoSpaceAfter)----------------------------------------------------------------------------------------------------------------PHPCBF CAN FIX THE 2 MARKED SNIFF VIOLATIONS AUTOMATICALLY----------------------------------------------------------------------------------------------------------------
您可以在上面的示例中看到 PSR12.Operators.OperatorSpacing.NoSpaceBefore
嗅探器。如果我们想在 Kernel.php
文件中忽略此嗅探器,可以将它添加到 app/Console/Kernel.php
文件中第 28 行附近。
// phpcs:disable PSR12.Operators.OperatorSpacing.NoSpaceAfter$this->load(__DIR__.'/Commands');// phpcs:enable
如果我们重新运行命令——这次针对 Kernel.php
文件——我们可以看到 NoSpaceAfter
规则已被禁用,但我们仍然得到 NoSpaceBefore
错误。
vendor/bin/phpcs -s --standard=PSR12 app/Console/Kernel.php FILE: /Users/paul/code/sandbox/phpcs-part-1/app/Console/Kernel.php----------------------------------------------------------------------------------------------------------------FOUND 1 ERROR AFFECTING 1 LINE---------------------------------------------------------------------------------------------------------------- 29 | ERROR | [x] Expected at least 1 space before "."; 0 found | | (PSR12.Operators.OperatorSpacing.NoSpaceBefore)----------------------------------------------------------------------------------------------------------------PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY----------------------------------------------------------------------------------------------------------------
我们可以通过逗号分隔嗅探器来为一组特定行禁用多个规则,例如
// phpcs:disable PSR12.Operators.OperatorSpacing.NoSpaceAfter, PSR12.Operators.OperatorSpacing.NoSpaceBefore$this->load(__DIR__.'/Commands');// phpcs:enable
最后,让我们恢复对 app/Console/Kernel.php
文件所做的所有更改。您会发现我们一直在用作示例的这两个规则与 Laravel Pint 直接冲突,Laravel Pint 期望在前后都有空格。
首先,让我们使用 phpcbf
自动修复上面的嗅探器。
vendor/bin/phpcbf --standard=PSR12 app PHPCBF RESULT SUMMARY----------------------------------------------------------------------------------------------FILE FIXED REMAINING----------------------------------------------------------------------------------------------/Users/paul/code/sandbox/phpcs-part-1/app/Models/User.php 1 0/Users/paul/code/sandbox/phpcs-part-1/app/Http/Controllers/Controller.php 1 0/Users/paul/code/sandbox/phpcs-part-1/app/Console/Kernel.php 2 0----------------------------------------------------------------------------------------------A TOTAL OF 4 ERRORS WERE FIXED IN 3 FILES----------------------------------------------------------------------------------------------
运行完后,让我们运行 Laravel Pint,看看它如何进行与 PHP Codesniffer 自动修复相反的操作。
$ vendor/bin/pint FIXED 54 files, 1 style issue fixed ✓ app/Console/Kernel.php concat_space
为了能够在开发和 CI 环境中使用这两个工具,我们需要选择一种风格,并使用一个工具强制执行它,并在另一个工具中禁用它。我更喜欢 Pint 的自动修复,所以我在 PHP Codesniffer 中禁用了冲突的嗅探器。
配置文件
让我们通过创建一个配置文件来解决 Pint 和 Codesniffer 之间的冲突。在一个应用程序中,我通常会创建一个 phpcs.xml
文件,但是如果您打算让其他人使用您的应用程序作为起点,您可以考虑使用 phpcs.xml.dist
。让我们将其创建为 phpcs.xml
<?xml version="1.0"?><!-- @see https://pear.php.net/manual/en/package.php.php-codesniffer.annotated-ruleset.php --><ruleset name= "Laravel PHPCS Rules"> <description>PHPCS ruleset for Example app.</description> <file>tests</file> <file>app</file> <!-- Show progress of the run --> <arg value= "p"/> <!-- Show sniff codes in all reports --> <arg value= "s"/> <!-- Our base rule: set to PSR12 --> <rule ref="PSR12"> <exclude name="PSR12.Operators.OperatorSpacing.NoSpaceBefore"/> <exclude name="PSR12.Operators.OperatorSpacing.NoSpaceAfter"/> </rule> <rule ref= "Generic.Files.LineLength"> <properties> <property name="lineLimit" value="80"/> <property name="absoluteLineLimit" value="120"/> </properties> </rule> <rule ref="PSR1.Methods.CamelCapsMethodName.NotCamelCaps"> <exclude-pattern>tests/</exclude-pattern> </rule> </ruleset>
您可以看到我将 -s
参数添加到配置中,因此所有报告都将显示嗅探器代码。我们还将目标设置为 app
和 test
目录,但请随时在您的项目中配置您希望 Codesniffer 检查的其他目录。
我们禁用了运算符间距嗅探器,因此 Pint 应该满意,PHP Codesniffer 现在将忽略这些规则。
我们还自定义了行长规则,使用 PSR-12 中的语言作为行限制和最大值的指南。这些嗅探器报告为警告,因此当您在 CI 中运行此工具时,您需要确保要么抑制警告,要么 CI 在有警告的情况下仍然通过。警告的目的是帮助您(开发人员)在开发过程中修复行长。
最后,NotCamelCaps
嗅探器在 tests
文件夹中被排除,因为我喜欢使用蛇形命名法编写 PHPUnit 测试。
/* @test */public function it_does_something_awesome()
现在,我们可以不带任何参数运行 phpcs
,它将加载我们的配置文件。您应该只看到关于行长和多个导入的警告。
vendor/bin/phpcs
您会注意到另一个违规是 MultipleImport
嗅探器,例如,这是由于以下行造成的
class User extends Authenticatable{ use HasApiTokens, HasFactory, Notifiable; // ...}
如果您愿意,可以随意禁用此嗅探器,或者可以使用 phpcbf
命令行 bin 自动修复它(使用我们的配置文件)。
vendor/bin/phpcbf.........F..........F.. 23 / 23 (100%) PHPCBF RESULT SUMMARY----------------------------------------------------------------------------------------------FILE FIXED REMAINING----------------------------------------------------------------------------------------------/Users/paul/code/sandbox/phpcs-part-1/app/Models/User.php 1 0/Users/paul/code/sandbox/phpcs-part-1/app/Http/Controllers/Controller.php 1 0----------------------------------------------------------------------------------------------A TOTAL OF 2 ERRORS WERE FIXED IN 2 FILES----------------------------------------------------------------------------------------------
结论
我们涵盖了很多内容,但您应该能够从头开始在 Laravel 中使用 PHP Codesniffer。如果您想针对 PHP CS Fixer 未执行的一些特定规则,它可以成为一个很好的补充,我已经教您如何禁用冲突的规则或您想禁用的规则。