composer cs-fix —— 代码风格修复工具 PHP-CS-Fixer
1. 什么是 PHP-CS-Fixer?
PHP-CS-Fixer 是由 Symfony 创始人 Fabien Potencier 发起的代码风格自动修复工具,是 PHP 生态中最主流的代码风格工具。
这个工具的核心价值在于:不仅检测代码风格问题,还能自动修复它们。在团队协作中,它能有效消除因个人编码习惯差异导致的风格冲突,让开发者把精力集中在业务逻辑而非格式调整上。
PHP-CS-Fixer 内置了丰富的规则集,包括:
@PSR12:PHP-FIG 官方推荐的最新编码标准@Symfony:Symfony 框架代码风格@PhpCsFixer:工具自身使用的严格规范@PER-CS:现代化 PHP 编码标准@PHP82Migration:PHP 8.2 迁移规则
2. 适用场景
| 场景 | 说明 |
|---|---|
| Git Pre-commit Hook | 提交前自动格式化暂存文件,阻止风格不合规的代码进入仓库 |
| CI/CD 流水线 | 在 Pull Request 中自动检查代码风格,不通过则阻止合并 |
| 团队协作 | 统一团队成员的编码风格,消除无意义的格式争论 |
| 遗留项目格式化 | 一键格式化整个代码库,快速建立统一标准 |
| IDE 集成 | 在 PhpStorm 等 IDE 中实现保存即格式化 |
最佳实践:配置分为两个层级——
composer cs-check(仅检查,不修改)用于 CI 流程;composer cs-fix(实际修复)用于本地开发。
3. 安装与初始化
3.1 通过 Composer 安装(推荐)
composer require --dev friendsofphp/php-cs-fixer
如果遇到依赖冲突,可以使用官方提供的 Shim 包:
composer require --dev php-cs-fixer/shim
3.2 快速初始化配置
PHP-CS-Fixer 提供了初始化命令,可快速生成基础配置文件:
./vendor/bin/php-cs-fixer init
执行后会生成 .php-cs-fixer.dist.php 文件,包含基础规则和路径配置。
3.3 在 composer.json 中定义脚本
{
"scripts": {
"cs-check": "php-cs-fixer check --dry-run",
"cs-fix": "php-cs-fixer fix"
}
}
注意:如果选择 Shim 包安装,命令前缀为
php-cs-fixer;如果通过普通 composer 包安装,命令路径为vendor/bin/php-cs-fixer。建议统一在 composer.json 的scripts中封装。
4. 配置文件深度解析
在项目根目录创建 .php-cs-fixer.dist.php 文件,这是推荐的项目级配置,应纳入版本控制。同时可创建 .php-cs-fixer.php 作为本地个性化配置,建议加入 .gitignore。
4.1 基础配置模板
<?php
// .php-cs-fixer.dist.php
declare(strict_types=1);
use PhpCsFixer\Config;
use PhpCsFixer\Finder;
$finder = Finder::create()
->in(__DIR__)
->exclude(['vendor', 'storage', 'bootstrap/cache', 'node_modules'])
->notPath('*.blade.php')
->notPath('_ide_*.php');
return (new Config())
->setFinder($finder)
->setRules([
// 使用 PSR-12 作为基础标准
'@PSR12' => true,
// 数组使用短语法 []
'array_syntax' => ['syntax' => 'short'],
// 移除未使用的 use 语句
'no_unused_imports' => true,
// 优先使用单引号
'single_quote' => true,
// 多行数组/参数尾部逗号
'trailing_comma_in_multiline' => true,
// 类属性按顺序排列(public, protected, private)
'ordered_class_elements' => true,
// import 语句按字母排序
'ordered_imports' => ['sort_algorithm' => 'alpha'],
// 严格的类型比较(===)
'strict_comparison' => true,
])
->setRiskyAllowed(true) // 允许可能改变代码行为的规则
->setIndent(" ") // 4个空格缩进
->setLineEnding("\n"); // Unix 换行符
4.2 路径精确控制
$finder = Finder::create()
// 指定要检查的目录
->in([
__DIR__ . '/src',
__DIR__ . '/tests',
__DIR__ . '/app',
__DIR__ . '/config',
__DIR__ . '/routes',
])
// 排除目录(仅对目录有效)
->exclude([
'src/Legacy',
'tests/Fixtures',
'app/Console/Commands/Deprecated'
])
// 排除具体文件(用 notPath)
->notPath([
'src/Config/constants.php',
'tests/bootstrap.php'
])
// 只检查 .php 文件(默认行为)
->name('*.php');
关键点:
exclude只对目录生效,排除单个文件必须使用notPath,且路径是相对于in()设置的路径。
4.3 规则集的组合与覆盖
->setRules([
// 基础规则集
'@PSR12' => true,
'@Symfony' => true,
// 覆盖规则集中的某个规则
'binary_operator_spaces' => [
'operators' => [
'=>' => 'single_space',
'=' => 'single_space',
]
],
'concat_space' => ['spacing' => 'one'],
// 关闭某个规则(即使它在规则集中被启用)
'align_multiline_comment' => false,
// 开启高风险规则(需 setRiskyAllowed(true))
'strict_comparison' => true,
'declare_strict_types' => true,
])
->setRiskyAllowed(true);
常用规则速查表:
| 规则名 | 作用 | 风险等级 |
|---|---|---|
@PSR12 | PSR-12 全部规则 | 安全 |
array_syntax | 短数组语法 | 安全 |
no_unused_imports | 移除未使用的 use | 安全 |
single_quote | 单引号优先 | 安全 |
strict_comparison | 严格比较 ===/!== | 中风险 |
declare_strict_types | 添加 declare(strict_types=1) | 中风险 |
native_function_invocation | 用原生函数替换 | 高风险 |
void_return | 添加 void 返回类型 | 高风险 |
4.4 使用共享配置
对于多项目团队,可以将配置抽取为独立的 Composer 包,实现统一管理:
composer require --dev your-team/php-coding-standard
然后在项目中引用:
// .php-cs-fixer.dist.php
use YourTeam\CodingStandard\PhpCsFixer\Config;
return Config::get($finder, $customRules);
4.5 自定义缩进和换行符
return (new Config())
->setIndent("\t") // 使用 Tab 缩进
->setLineEnding("\r\n") // Windows 换行符
// ... 其他配置
5. 使用方法
5.1 基础命令
# 检查(仅报告,不修改)
./vendor/bin/php-cs-fixer check --dry-run
# 执行修复
./vendor/bin/php-cs-fixer fix
# 指定配置文件(默认自动检测)
./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php
# 修复特定目录
./vendor/bin/php-cs-fixer fix src/Controller/
5.2 输出示例
执行 ./vendor/bin/php-cs-fixer check --dry-run 的输出:
PHP CS Fixer 3.89.1 Folding Bike by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.4.2
Running analysis on 1 core sequentially.
You can enable parallel runner and speed up the analysis! Please see usage docs for more information.
Loaded config default from "/project/.php-cs-fixer.dist.php".
Using cache file ".php-cs-fixer.cache".
20/20 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
1) tests/Feature/Email/DomainIsNotTest.php
2) src/Email.php
Found 2 of 20 files that can be fixed in 0.026 seconds, 20.00 MB memory used
5.3 并行模式加速
对于大型项目,PHP-CS-Fixer 支持并行执行以显著提升速度:
// 在配置文件中启用
use PhpCsFixer\Runner\Parallel\ParallelConfig;
return (new Config())
->setParallelConfig(new ParallelConfig(4, 20)) // 4进程,每进程20文件
// ...
5.4 在 PhpStorm 中集成
PhpStorm 提供了原生支持:
- 进入 Settings → PHP → Quality Tools → PHP CS Fixer
- 工具会自动检测
vendor/bin/php-cs-fixer路径 - 点击 Validate 验证配置
- 配置 Run mode:
- On the fly:输入时自动检查并高亮问题
- On idle:停止输入后延迟执行
- On save:仅在保存文件时触发
- 勾选 Allow risky rules(如需要)
6. Git Pre-commit Hook 实战
在 Git 提交前自动检查代码风格,可以阻止不合规的代码进入仓库。
6.1 使用现成的 Hook 脚本
推荐的 gerardroche/php-cs-fixer-pre-commit-hook:
# 安装
git clone https://github.com/gerardroche/php-cs-fixer-pre-commit-hook.git
cd php-cs-fixer-pre-commit-hook
./install
该 Hook 的特点:
- 仅检查本次变更的文件(非全量扫描)
- 发现问题时阻止提交并输出报告
- 可通过
git commit --no-verify绕过
6.2 自定义 Pre-commit Hook
#!/bin/sh
# .git/hooks/pre-commit
PROJECT_ROOT=$(git rev-parse --show-toplevel)
cd "$PROJECT_ROOT" || exit 1
# 获取本次变更的 PHP 文件
CHANGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.php$' | tr '\n' ' ')
if [ -n "$CHANGED_FILES" ]; then
echo "Running PHP CS Fixer on staged files..."
./vendor/bin/php-cs-fixer fix --dry-run --format=txt $CHANGED_FILES
if [ $? -ne 0 ]; then
echo "❌ Coding standards violations found. Please run:"
echo " ./vendor/bin/php-cs-fixer fix $CHANGED_FILES"
echo " and then git add the fixed files."
exit 1
fi
fi
7. CI/CD 集成(GitHub Actions)
在 Pull Request 中自动检查代码风格:
# .github/workflows/cs.yml
name: Code Style Check
on:
pull_request:
push:
branches: [main, develop]
jobs:
cs-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
tools: composer
- name: Install dependencies
run: composer install --no-progress
- name: Run CS Fixer Check
run: composer cs-check
如果检查失败,PR 将显示 ❌ 状态,阻止合并。
8. 完整案例:为新项目建立代码风格规范
场景
你有一个新启动的 PHP 项目,需要建立统一的代码风格规范并集成到开发流程中。
步骤一:安装并生成配置
composer require --dev friendsofphp/php-cs-fixer
./vendor/bin/php-cs-fixer init
步骤二:完善配置文件
创建 .php-cs-fixer.dist.php,配置团队选定的规则(参考第 4 节的模板)。
步骤三:添加 Composer 脚本
{
"scripts": {
"cs-check": "php-cs-fixer check --dry-run",
"cs-fix": "php-cs-fixer fix",
"test": "phpunit",
"analyse": "phpstan analyse"
}
}
步骤四:在开发文档中记录工作流
在 README.md 中添加:
## 代码风格
本项目使用 PHP-CS-Fixer 统一代码风格。
### 本地开发
- 提交前执行:`composer cs-fix`
- 仅检查:`composer cs-check`
### CI 检查
PR 会自动运行 `composer cs-check`,不通过则无法合并。
步骤五:配置 Pre-commit Hook
参考第 6 节设置 Git Hook,确保提交时自动检查。
步骤六:设置 IDE(PhpStorm)
参考第 5.4 节,让团队成员在保存时自动格式化,从源头减少风格问题。
9. 常见问题与故障排查
| 问题 | 解决方案 |
|---|---|
Command "check" is not defined | 检查 PHP-CS-Fixer 版本,check 命令在 v3.0+ 引入 |
| 规则不生效 | 确认配置文件名为 .php-cs-fixer.dist.php 或 .php-cs-fixer.php,且位于项目根目录 |
| CI 中报错但本地正常 | 检查 CI 环境的 PHP 版本与本地是否一致 |
执行 fix 后代码逻辑被改变 | 检查是否启用了 risky 规则,通常应避免在生产代码中使用高风险规则 |
| 并行模式报错 | 降低 ParallelConfig 的进程数或禁用并行模式 |
通过上述配置和实践,你的团队可以建立起一套高效、自动化的代码风格管理流程,让 PHP-CS-Fixer 成为代码质量的坚实防线。