Happy New Year!
编程

引入 PHP-CS-Fixer 到老项目中

394 2023-05-05 02:48:00

您正在处理一个遗留的PHP项目,并希望使用 friendsofphp/php-cs-fixer 来强制执行一致的编码标准。但你不确定如何在不造成问题的情况下做到这一点。

在您的遗留PHP中引入PHP CS Fixer以降低风险并邀请其他开发人员进行合作,应该采取什么样的策略?

要求

如果你想在你的遗留PHP项目中成功地引入PHP CS Fixer,你将有以下要求:

  • 您希望在您的持续集成系统中运行PHP CS Fixer。当您提交和推送不符合编码标准的代码时,您希望持续集成系统中的构建失败。
  • 您希望在您的开发环境中运行PHP CS Fixer。当您更改PHP代码和不符合编码标准的代码时,您希望PHP CS Fixer修复违反编码标准的问题。您不需要在开发环境中报告违反编码标准的情况;你想直接去修复。您还需要一个简单的命令来在开发环境中运行PHP CS Fixer,这样您就可以频繁地运行它。
  • 您希望PHP CS Fixer只应用与您在生产中使用的PHP版本兼容的修复程序。如果您的项目运行在PHP 5.3上,您不希望PHP CS Fixer 将需要运行在PHP 8.1上的修复程序在5.3上运行。

安装 PHP-CS-Fixer

您可以使用composer、phive或从发布页面下载PHAR来安装PHP CS Fixer。但您可以在PHP CS Fixer的README.md中详细研究PHP CS Fixter的安装选项和说明;我不会在这里重复。

我建议使用composer来安装PHP CS Fixer,这样您就可以从可靠的、Renovatebot或类似服务的自动依赖更新中受益。如果您使用phive安装PHP CS Fixer或从发布页面下载,则必须手动更新PHP CS Fixer。

你的项目还没有使用composer?为什么不通过将PHP CS Fixer作为您的第一个开发依赖项来开始使用composer呢?

您不能使用composer,因为您的项目在生产中还没有在PHP 5.3上运行?为什么不使用不同版本的PHP来运行开发工具呢?

我还建议使用最新版本的PHP CS Fixer,这样您就可以从维护人员和贡献者不断添加到工具中的功能和修复中受益。

你不能使用最新版本的PHP CS Fixer,因为你的项目还没有在生产中运行PHP 7.4或更高版本?同样,为什么不使用不同版本的PHP来运行开发工具呢?

例如,在过去的几周里,我一直忙于将一个项目从PHP 5.6升级到PHP 8.1。在Docker中设置了一个在PHP 5.6上运行的本地开发环境后,我已经建立了一个GitHub Actions工作流,该工作流使用PHP 8.1安装和运行开发工具,包括PHP CS Fixer。

如果我可以使用PHP8.1为一个在生产中运行PHP5.6的项目运行开发工具,那么你也可以。

成功的关键是对开发工具进行仔细的配置。

为 PHP-CS-Fixer 添加一些基础配置 

PHP CS Fixer需要两件事来报告和修复违反编码标准的行为:一份应该检查的文件列表,以及一份用于创建和配置相应修复程序的规则和规则集的配置。

下面的配置文件.php-cs-fixer.php配置了一个查找器和一个空的规则数组。

<?php

$finder = PhpCsFixer\Finder::create()
    ->exclude([
        '.build/',
        '.docker/',
        '.github/',
    ])
    ->ignoreDotFiles(false)
    ->in(__DIR__)
    ->name('.php-cs-fixer.php');

$config = new PhpCsFixer\Config();

$config
    ->setFinder($finder);
    ->setRules([]);

return $config;

finder允许您配置目录、排除项、文件名等的列表,并返回PHP-CS-Fixer应该检查的文件列表。

根据您的项目布局,您的查找器配置可能会有所不同。

空的规则数组将覆盖默认规则配置。PHP CS Fixer在应用修复程序之前和之后对PHP文件进行lint处理,以确保它既不会试图修复包含无效PHP代码的文件,也不会留下包含无效PHP码的文件。当PHP CS Fixer发现一个文件不包含有效的PHP代码时,它将跳过修复并发出警告。

即使使用一个空的规则数组,PHP CS Fixer对你来说也是一个很有价值的工具,因为它可以帮助你找到包含无效PHP代码的文件。

既然有了PHP-CS-Fixer初始配置,我们开始运行 PHP-CS-Fixer吧。

在GitHub Action中运行 PHP-CS-Fixer

如前所述,你会在两个环境中运行 PHP-CS-Fixer:你的持续集成(CI)系统中和本地开发环境中。

下面的命令会使用 --dry-run 选项运行 PHP-CS-Fixer,并报告代码标准违规:

vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --diff --dry-run --verbose

根据您安装PHP CS Fixer和命名配置文件的方式,该命令可能会有所不同。

但在连续集成系统中运行PHP CS Fixer时,使用--dry-run选项很重要:当发现违反编码标准构建时,PHP CS Fixr将以非零退出码结束执行并退出构建。

我在GitHub感到宾至如归,喜欢使用GitHub Actions作为一个持续集成系统。下面的GitHub Action工作流将检查您的repository存储库,设置PHP,使用composer安装依赖项,并使用--dry-run选项运行PHP CS Fixer。

name: "Integrate"

on:
  pull_request: null
  push:
    branches:
      - "main"

jobs:
  coding-standards:
    name: "Coding Standards"

    runs-on: "ubuntu-latest"

    strategy:
      matrix:
        php-version:
          - "8.1"

    steps:
      - name: "Checkout"
        uses: "actions/checkout@v3.5.0"

      - name: "Set up PHP"
        uses: "shivammathur/setup-php@v2.24.0"
        with:
          coverage: "none"
          php-version: "${{ matrix.php-version }}"

      - name: "Validate composer.json and composer.lock"
        run: "composer validate --ansi --no-check-publish"

      - name: "Install locked dependencies with composer"
        run: "composer install --ansi --no-interaction --no-progress"

      - name: "Run friendsofphp/php-cs-fixer"
        run: "vendor/bin/php-cs-fixer fix --ansi --config=.php-cs-fixer.php --diff --dry-run --verbose"

根据您的项目设置和持续集成系统,您的配置可能会有所不同,但步骤大致相同。

有了这个GitHub Actions工作流,您就无法提交和推送不符合您的编码标准的PHP代码而不造成编译失败。

💡 您可以通过在缓存composer安装的依赖项和PHP-CS-Fixer的缓存文件来改进coding-standards任务。

在开发环境中运行 PHP-CS-Fixer

下面命令会运行 PHP-CS-Fixer 并修复违反代码标准的问题:

vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --diff --verbose

根据您安装PHP CS Fixer和命名配置文件的方式,该命令可能会有所不同。同样,您不关心在开发环境中报告违反编码标准的情况;你将直接进行修复。

该命令键入起来有点长,如果你想经常运行PHP CS Fixer,你可能想使用任务运行程序或其他一些工具,这样可以更容易地在开发环境中运行工具。

如果您使用Makefile,请将编码标准目标添加到您的Makefile中。

.PHONY: coding-standards
coding-standards: vendor
	vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --diff --verbose

vendor: composer.json composer.lock
	composer validate --strict
	composer install --no-interaction --no-progress

有了Makefile中的编码标准目标,您可以运行以下命令,让PHP CS Fixer修复违反编码标准的问题:

make coding-standards

💡 如果您还没有使用Makefile,或者发现命令仍然太长,请阅读懒人版Makefile手册。

如果您更喜欢composer脚本,请在composer.json中添加一个编码标准脚本。 

如果你偏向于 Composer 脚本, 添加 code-standards 脚本到你的 composer.json。

{
  "scripts": {
    "coding-standards": "@php vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --diff --verbose"
  }
}

在你的 composer.json 中有了 code-standard 脚本,你可以运行如下命令让 PHP-CS-Fixer 修复违反代码标准的问题:

composer coding-standards

PHP CS Fixer配置的演变

现在,您已经在持续集成系统和开发环境中运行PHP CS Fixer,还剩一件事:您希望PHP CS Fixr 使用与您在生产中使用的PHP版本兼容的修复程序,而到目前为止,您只配置了一个空的规则数组。

以下是对我有效的方法。

首先,获取所有可用修复程序的完整规则列表,例如,来自lergebnis/php-cs-fixer-config-template的自定义规则集。

其次,调整规则配置以进行配置,但禁用所有这些修复程序。在撰写本文时,应该有250条规则。

<?php

$finder = PhpCsFixer\Finder::create()
    ->exclude([
        '.build/',
        '.docker/',
        '.github/',
    ])
    ->ignoreDotFiles(false)
    ->in(__DIR__)
    ->name('.php-cs-fixer.php');

$config = new PhpCsFixer\Config();

$config
    ->setFinder($finder);
    ->setRules([
        'align_multiline_comment' => false,
        'array_indentation' => false,
        'array_push' => false,
        'array_syntax' => false,
        // ...
        'visibility_required' => false,
        'void_return' => false,
        'whitespace_after_comma_in_array' => false,
        'yoda_style' => false,
   ]);

return $config;

💡 或者,如果您已经跨项目共享PHP CS Fixer的配置,如跨项目共享PHP CS Fixer配置中所述,请通过禁用所有规则来覆盖现有的规则配置。

第三,从上到下或从下到上,看你哪个更适合你,浏览规则列表,选择一个规则,仔细检查它的文档,并一次启用和配置一个规则-但前提是您可以确保它只应用与生产中运行的PHP版本兼容的修复程序。

一次启用和配置一条规则的示例

让我们看看具体的例子,当您处理拉取请求和合并前代码审查时,考虑并配置array_syntax规则。

  • 首先,创建一个分支,比如 feature/array-syntax。
  • 其次,辅助规则名称。
  • 第三,导航到https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.16.0(将3.16.0替换为您实际使用的PHP CS Fixer版本)。按T键打开文件导航。将规则的名称粘贴到输入字段中(此处为array_syntax)。在下拉列表中选择相应的文档文件(此处为array_syntax.rst)。

第四,检查文件。你能安全地启用array_syntax修复程序吗?例如,PHP 5.4引入了短数组语法。您的遗留PHP项目是否在生产中运行在PHP 5.3上?然后,您可能应该启用array_syntax修复程序,并将语法选项配置为使用long作为值。或者您的遗留PHP项目是否运行在PHP 5.4或更高版本上?然后,您可能应该启用修复程序,并将语法选项配置为使用short as value。

  • 第五,将更改提交并推送到.php-cs-fixer.php配置文件。
  • 第六,打开一个pull请求,并在正文中说明这个pull请求将启用array_syntax修复程序。打开拉取请求将启动GitHub Actions工作流的运行。
  • 第七,在您的开发环境中运行PHP CS Fixer。如果PHP CS Fixer已经应用了修复程序,那么GitHub Actions工作流将失败。提交并在单独的提交中推送修复程序,以使构建通过。
  • 第八,审查拉取请求中的更改,并验证这些更改是否合理。如果有必要,让其他人也审查你的PR请求。
  • 第九,合并拉取请求并删除分支。
  • 第十,检查开发环境中的默认分支。
  • 第十一,拉取最新变化。
  • 第十二,删除特征分支。

为每个规则重复上述动作。

一次启用和配置一条规则的缺点

在撰写本文时,PHP CS Fixer附带了250条规则。一次启用和配置一个规则可能需要一段时间,尤其是当您处理拉取请求并需要进行合并前代码审查时。但是,您可以通过使用Ship/Show/Aask显著加快流程。

如果你不愿意投入时间,可以一次应用所有规则并审查所有修复,祝你好运!

一次启用和配置一个规则的优点

在我看来,一次启用和配置单个规则具有以下优势:

  • 您可以最大限度地降低风险:每个拉取请求只包含更容易审查的相关更改。

您邀请其他开发人员就您的编码标准进行合作。

您可能会在遗留PHP项目各个角落的代码修改代码,这使您能够发现并注意到需要仔细检查的奇怪地方。

 

PHP