在项目和团队之间共享 PHP-CS-Fixer 规则
PHP-CS-Fixer 是一个开源工具,它可以强制执行和检测违反 PHP 编码风格的行为。 使用预定义的规则,它可以使您拥有严格的编码风格,该风格由工具强制执行,因此您可以将时间花在更重要的事情上。
规则案例
这是 PHP-CS-Fixer 可以对您的代码库执行的操作的一些示例:
Rule: is_null
将 is_null($var)
表达式替换为 $var === null
.
// before...
if (is_null($account->closed_at)) {
//
}
// after...
if ($account->closed_at === null) {
//
}
Rule: mb_str_functions
用相应的 mb 函数替换多字节不安全函数。
// before...
$length = strlen($request->post('slug'));
// after...
$length = mb_strlen($request->post('slug'));
Rule: not_operator_with_successor_space
逻辑运算符 (!)
后必须紧跟一个空格。
// before...
- if (!$user->is_active) {
//
}
// after...
if (! $user->is_active) {
//
}
可用的规则非常全面,并且数量不断增加。 您可以在 项目的 redme 文件 中查看可用规则的完整列表。 您可能还想看看 PHP-CS-Fixer配置,语言无法描述清楚的话, 该站点还提供了每个规则的作用示例。
热门提示:除了固定样式外,它通常还可以用作升级工具。 PHPUnit 8 在几种方法中添加了一个 void
返回类型。 在 /tests
目录中运行 PHP-CS-Fixer 的 void_return 规则可以立即升级您的测试套件,使其与这些更改兼容。
共享规则
如果在整个项目中使用都 PHP-CS-Fixer ,并且有一个定义代码风格的规则集。到目前为止,我新建一个项目时,我一直在复制粘贴规则,如果出现新规则,我必须更新配置,这并不是一个理想的工作流程。因为很容易遗漏更新某个项目,毕竟这是一堆手动工作。
事实证明,我们可以在多个项目和团队中共享规则, 因此我们所有的项目 composer update
时都可以随时使用最新版本的规则集。
搭建代码库
我们将建立一个代码库来存储规则集。首先我们初始化本地代码库并创建所需文件:
$ mkdir php-styles
$ cd php-styles
$ git init
$ echo "/composer.lock
/vendor
/.php_cs.cache" >> .gitignore
$ mkdir src
$ touch src/rules.php src/helpers.php composer.json
定义规则
正如我之前提到的,可能有很多规则,新版本有时还会增加新规则,因此,我发现跟踪上一次可用规则的 PHP-CS-Fixer 版本是非常方便。这意味着,当您升级到较新的版本时,您将知道要查找的发行版,以查找可能要合并到共享规则集中的新规则。我想在rules.php
文件顶部添加最新的审阅版本。
<?php
// last reviewed: v2.16.3 Yellow Bird
接下来,我们要使我们的 rules.php
文件返回一个包含规则集的数组。 将规则放在单独的文件中会比较方便,因为列表可能会很长,具体取决于您的规范。 它还允许其他开发人员引入您的规则集,并将其与自己的规则集合并,例如,如果您想引入 Laravel 编码标准,并将其与团队其他一些标准结合在一起。
<?php
// last reviewed: v2.16.3 Yellow Bird
return [
'@PSR2' => true,
'array_syntax' => ['syntax' => 'short'],
'final_class' => false,
'new_with_braces' => true,
// ...
];
PHP-CS-Fixer 预定义了一些规则集。 与PSR-2标准有关的所有规则都捆绑在规则集@ PSR2中。 这使我们可以选择加入标准,而不必单独指定每个规则。
一些规则具有与之关联的选项。 使用 array_syntax 规则可以指定是短数组还是长数组语法。
其他规则在列表中通过使用它们的名称和布尔值来指定,如 new_with_braces 规则所示。 尽管您可以省略布尔值,但是为了保持一致性,我喜欢将其包括在内,因此数组中的每个项目都是 key ⇒ value
形式,因此我知道我明确选择了特定规则。
辅助方法
为了使您在整个项目中都能轻松使用共享规则,我们创建了一个辅助函数。 为什么会有这种想法呢?继续往下看你就会明白。
为确保该函数与项目中的任何其他全局函数或其依赖项不冲突,将函数放在命名空间中是一个好主意。 打开 helpers.php
文件并定义一个对您的上下文有意义的命名空间。
<?php
namespace TiMacDonald;
现在我们需要定义方法。 该方法接受 PhpCsFixer \ Finder
的实例以及一系列规则,这些规则将使项目可以逐个地识别任何其他强制性规则。 通常我们希望保持一致性,并且不允许任何项目更改共享规则集-但这不是本文讨论的话题。我们您这样做,如果您愿意也可以保留删除功能。
<?php
namespace TiMacDonald;
use PhpCsFixer\Config;
use PhpCsFixer\Finder;
function styles(Finder $finder, array $rules = []): Config {
//
}
很好,完成的差不多了。 现在的最后一件事是填写辅助函数的正文。
<?php
namespace TiMacDonald;
use PhpCsFixer\Config;
use PhpCsFixer\Finder;
function styles(Finder $finder, array $rules = []): Config {
$rules = array_merge(require __DIR__.'/rules.php', $rules);
return Config::create()
->setFinder($finder)
->setRiskyAllowed(true)
->setRules($rules);
}
$finder
可以让 PHP-CS-Fixer 应该在哪里查找要修复的 PHP 文件。 我们将此 $finder
的定义放到单独项目中,因为每个项目都可能具有不同的目录结构,例如,Laravel 软件包和一个 Laravel 项目。
高风险规则
在 styles 函数的主体内,您可以看到我们通过调用 setRiskyAllowed(true)
告诉配置允许 risky
规则。 您必须阅读文档并了解高风险规则可能如何影响您的项目。 举例来说,我们来看看 implode_call
规则。 如果您阅读了 implode 相关的PHP文档,则会注意到:
由于历史原因,implode() 可以按任一顺序接受其参数。 为了与explode() 保持一致,不建议使用记录的参数顺序。
这以为这这两个 implode 语句会得到相同的结果:
<?php
implode($array, ',');
implode(',', $array);
implode_call
规则会重新排列参数的顺序,但是如果您的项目已经重新定义了 implode()
方法,则会通过某种方式期望参数以错误的顺序排列,例如 runkit, 更改顺序可能会破坏您的代码。
因此,在将其添加到规则集中之前,请仔细阅读每条有风险的规则的功能并了解其工作原理。
composer.json
如归需要安装新的扩展包, 我们需要修改 composer.json
文件。我建议在持续集成中运行代码风格检查,因此我在本地安装 PHP-CS-Fixer (如果扩展包有冲突的话,你也可以下载 PHP-CS-Fixer 的 Phar 文件).
打开 composer.json
文件并且确保设置一个唯一且有意的 name
。
{
"name": "timacdonald/php-style-example",
"description": "Tim's shared PHP style rules for PHP-CS-Fixer",
"license": "MIT",
"require": {
"friendsofphp/php-cs-fixer": "^2.0"
},
"autoload": {
"files": [
"./src/helpers.php"
]
}
}
将规则库托管
最后一步操作是将我们的本地规则仓库与远程仓库关联,然后将其推送到 GITHUB 托管。下面是操作命令:
$ git add .
$ git commit -m wip
$ git remote add origin git@github.com:timacdonald/php-style-example.git
$ git push -u origin master
至此,我们已经将我们的规则实现共享了!
使用共享规则库
现在我们只要做一些小的调整,就可以使用我们的共享规则库了。现在关闭共享规则库,然后在本地创建一个新的应用,初始化项目并执行 composer update
。
导入扩展包
Composer 允许我们直接通过 GIT 平台导入你需要的扩展包,而不用必须发布在 Packagist 上面。 考虑到会有这种只会在公司内部使用的扩展的情况,将它发布到 Packagist 意义不大。
为此,你需要将你的扩展添加到 "require-dev"
区块,这里,我并不需要锁定他的某个特定版本,所以我用 "dev-master"
,这样做意味着我的项目每次都会采用最新的版本的扩展。当然,这这个设置并不是必须的,你可以视你项目而定。
因为我们的扩展并未发布到 Packagist ,所以在 repositories 区块中,我们还需要告诉 Composer 去哪里寻找我的的扩展 repositories。具体请看代码:
"repositories": [
{
"type": "vcs",
"url": "https://github.com/timacdonald/php-style-example"
}
]
现在我们通过 composer 的 --dev
参数来加载依赖。
$ composer require timacdonald/php-style-example --dev
设置 PHP-CS-Fixer 查找器的配置
为了让 PHP-CS-Fixer 知道要定位的文件,您需要使用 PhpCsFixer\Finder
的实例指定每个目录或文件。 这是 Symfony\Component\Finder\Finder
的继承版本,因此,有关要使用的所有约束的完整文档,请 查看文档。
对于我们的示例,假定我们在 Laravel 应用程序中,设置查找程序来搜索需要遵守样式约定的目录。
PHP-CS-Fixer 的配置项位于 /.php_cs.dist
文件,因此我们创建一个:
$ touch .php_cs.dist
打开此文件,然后为您的 Laravel 应用添加以下查找程序设置。 您还可以包括要修复的其他任何文件夹,但是这些文件夹是合理的默认值。
<?php
$finder = PhpCsFixer\Finder::create()
->in([
__DIR__.'/app',
__DIR__.'/config',
__DIR__.'/database',
__DIR__.'/routes',
__DIR__.'/tests',
]);
现在,我们准备将查找器传递给刚刚创建的辅助函数。 PHP-CS-Fixer 希望该文件返回 PhpCsFixer\Config
的实例,这正是我们的辅助函数返回的内容。
<?php
$finder = PhpCsFixer\Finder::create()
->in([
__DIR__.'/app',
__DIR__.'/config',
__DIR__.'/database',
__DIR__.'/routes',
__DIR__.'/tests',
]);
return TiMacDonald\styles($finder);
现在,您将光标放在大括号位置,将自动修复所有这些目录中的编码样式! 跳至终端并运行以下命令以观看魔术的发生…
./vendor/bin/php-cs-fixer fix
CI 期间执行
在 C.I. 期间强制执行样式规则是一个好主意。 您可以通过以下两种方式执行此操作:您可以执行 “dry run”,如果它检测到代码样式违规,则将失败。
./vendor/bin/php-cs-fixer fix --dry-run
或者,您可能需要 C.I. 运行修复程序并将更改自动提交到您的代码库。 如果您正在使用 GitHub上 的动作,看看这篇很棒的文章 ,由 Stefan Zweifel 写的 关于如何实现上述操作的文章。
总结
感谢您的旅程。 PHP-CS-Fixer 是一个很棒的工具,如果您希望运行多个共享标准编码样式的项目,这种方法可能会派上用场。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
👍👍👍 赞一个
谁给共享一个比较全面对 php_cs.dist 哈