在 Laravel 中使用 PHP Codesniffer

发布于 作者:

Using PHP Codesniffer With Laravel image

从 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 --git
cd phpcs-part-1

git 标志将安装新的 Laravel 应用程序,初始化 git,并将所有内容提交到版本控制。这让我们得到一个干净的起点,可以查看我们在本教程中进行的更改。

接下来,让我们将 PHP Codesniffer 作为开发依赖项安装。

composer require --dev squizlabs/php_codesniffer

注意:在撰写本文时,所需的命令安装版本 ^3.7,但您的版本可能略有不同,这并不重要。

如果您从命令行运行 phpcs,您会看到它要求您指定路径。

$ vendor/bin/phpcs
ERROR: You must supply at least one file or directory to process.
 
Run "phpcs --help" for usage information

不用担心,我们将在下一步添加一个配置文件来指定 PHPCS 应该包含(和排除)哪些路径,但是如果您使用默认规则集(Pear)运行它,您将在默认的 Laravel 安装中得到一堆错误。

$ vendor/bin/phpcs -v app
Registering 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 参数添加到配置中,因此所有报告都将显示嗅探器代码。我们还将目标设置为 apptest 目录,但请随时在您的项目中配置您希望 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 未执行的一些特定规则,它可以成为一个很好的补充,我已经教您如何禁用冲突的规则或您想禁用的规则。

Paul Redmond photo

Laravel News 的撰稿人。全栈 Web 开发人员和作家。

Cube

Laravel 新闻

加入 40,000 多名其他开发人员,绝不错过新的技巧、教程等。

Laravel Forge logo

Laravel Forge

轻松创建和管理您的服务器,并在几秒钟内部署您的 Laravel 应用程序。

Laravel Forge
Tinkerwell logo

Tinkerwell

Laravel 开发人员必备的代码运行器。 使用 AI、自动完成和对本地和生产环境的即时反馈进行调试。

Tinkerwell
No Compromises logo

不妥协

Joel 和 Aaron,来自“不妥协”播客的两名经验丰富的开发者,现在可以为您的 Laravel 项目提供服务。 ⬧ 固定费率为每月 7500 美元。 ⬧ 无需冗长的销售流程。 ⬧ 无需合同。 ⬧ 100% 退款保证。

不妥协
Kirschbaum logo

Kirschbaum

提供创新和稳定性,确保您的 Web 应用程序取得成功。

Kirschbaum
Shift logo

Shift

运行旧版本的 Laravel? 即时、自动化的 Laravel 升级和代码现代化,让您的应用程序保持新鲜。

Shift
Bacancy logo

Bacancy

使用经验丰富的 Laravel 开发人员为您的项目增效,他们拥有 4-6 年的经验,每月仅需 2500 美元。 获取 160 小时的专业知识和 15 天的免费试用。 立即安排通话!

Bacancy
Lucky Media logo

Lucky Media

现在就变得幸运 - Laravel 开发的理想选择,拥有超过十年的经验!

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar:Laravel 电子商务

Laravel 的电子商务。 一个开源软件包,将现代无头电子商务功能的强大功能带入 Laravel。

Lunar:Laravel 电子商务
LaraJobs logo

LaraJobs

官方 Laravel 招聘网站

LaraJobs
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit:Laravel SaaS 启动套件

SaaSykit 是一个 Laravel SaaS 启动套件,它包含运行现代 SaaS 所需的所有功能。 付款、漂亮的结账、管理面板、用户仪表板、身份验证、现成的组件、统计信息、博客、文档等等。

SaaSykit:Laravel SaaS 启动套件
Rector logo

Rector

您无缝升级 Laravel、降低成本和加速创新的合作伙伴,助力企业取得成功

Rector
MongoDB logo

MongoDB

通过 MongoDB 和 Laravel 的强大集成来增强您的 PHP 应用程序,使开发人员能够轻松高效地构建应用程序。 支持事务性、搜索、分析和移动用例,同时使用熟悉的 Eloquent API。 探索 MongoDB 的灵活、现代数据库如何改变您的 Laravel 应用程序。

MongoDB
Maska is a Simple Zero-dependency Input Mask Library image

Maska 是一个简单的零依赖输入掩码库

阅读文章
Add Swagger UI to Your Laravel Application image

将 Swagger UI 添加到您的 Laravel 应用程序

阅读文章
Assert the Exact JSON Structure of a Response in Laravel 11.19 image

在 Laravel 11.19 中断言响应的精确 JSON 结构

阅读文章
Build SSH Apps with PHP and Laravel Prompts image

使用 PHP 和 Laravel 提示构建 SSH 应用程序

阅读文章
Building fast, fuzzy site search with Laravel and Typesense image

使用 Laravel 和 Typesense 构建快速、模糊的网站搜索

阅读文章
Add Comments to your Laravel Application with the Commenter Package image

使用 Commenter 软件包为您的 Laravel 应用程序添加评论

阅读文章