必须本地安装,不能全局装;规则必须写在.php-cs-fixer.php里——因全局安装导致多项目共享同一版本,无法适配不同PHP语法特性与规则需求,且CI环境常缺失全局PATH,而项目级安装可锁定版本、自动加载配置、确保环境一致与可复现。

必须本地安装,不能全局装;规则必须写在 .php-cs-fixer.php 里,不能硬塞进 composer.json 或用 --rules 临时拼 JSON。
为什么不能用 composer global require
全局安装会让所有项目共享同一个 php-cs-fixer 二进制,但不同项目依赖的 PHP 版本、语法特性(比如 match 表达式或属性提升)需要对应版本的规则集。v3.52 可能跳过 PHP 8.2 的新语法修复,而 v3.60 才支持——全局命令无法按项目切换。
更实际的问题是:~/.composer/vendor/bin/php-cs-fixer 很可能不在 CI 环境的 $PATH 中,导致流水线直接报 Command "php-cs-fixer" not found。
- CI 脚本里必须写
./vendor/bin/php-cs-fixer才可靠 -
composer show friendsofphp/php-cs-fixer查到的版本,和你本地php-cs-fixer --version显示的,很可能不一致 - 团队新人
git clone && composer install后,立刻就能跑通cs:fix,前提是它只依赖vendor/bin/和根目录配置
composer.json 里 scripts 怎么写才不报错
常见错误是写成 "cs:fix": "php-cs-fixer fix",结果提示命令未找到——因为 Composer 不会自动把 vendor/bin 加进 PATH,它只认显式路径。
立即学习“PHP免费学习笔记(深入)”;
正确写法必须带前缀,并启用可调试输出:
"scripts": {
"cs:fix": "vendor/bin/php-cs-fixer fix --verbose --diff",
"cs:check": "vendor/bin/php-cs-fixer fix --dry-run --diff"
}-
--verbose显示哪些文件被修改,避免“悄无声息修了一堆” -
--diff输出具体变更内容,方便 Code Review 时快速确认 - 不要加
--config参数:只要.php-cs-fixer.php在项目根目录,它会自动加载 - 如果想限制只处理 Git 暂存区文件(例如 pre-commit 场景),加
--path-mode=intersection
.php-cs-fixer.php 配置文件怎么写才生效
文件名必须一字不差,大小写敏感,且必须放在项目根目录。PHP CS Fixer v3 不识别 .php_cs、php-cs-fixer.php 或 config.php。
最小可用配置示例(注意 return 不能漏):
<?php
$finder = PhpCsFixer\Finder::create()
->in(['src', 'tests'])
->name('*.php')
->notName('index.php')
->ignoreDotFiles(true)
->ignoreVCS(true);
<p>return (new PhpCsFixer\Config())
->setRules([
'@PSR12' => true,
'array_syntax' => ['syntax' => 'short'],
'no_unused_imports' => true,
'trailing_comma_in_multiline' => true,
])
->setFinder($finder);</p>-
setFinder()必须明确限定目录,否则可能误处理vendor/或生成的blade.php文件 - 规则名大小写和符号严格匹配,
@PSR12不是psr12,no_unused_imports不能写成no-unused-imports - 若项目用 Laravel,慎用
no_unused_imports——它可能删掉use Illuminate\Support\Facades\DB;这类 Facade 别名
Git pre-commit 钩子里调用失败怎么办
钩子执行时工作目录可能是 .git/ 子目录,PATH 也不含 vendor/bin,所以直接写 composer run cs:fix 或 php-cs-fixer 几乎必挂。
最稳的方式是用绝对路径调用,并加 --dry-run 预检:
#!/bin/sh # .git/hooks/pre-commit cd "$(git rev-parse --show-toplevel)" || exit 1 if ! ./vendor/bin/php-cs-fixer fix --dry-run --using-cache=no >/dev/null 2>&1; then echo "❌ PHP code style check failed. Run 'composer cs:fix' to auto-fix." exit 1 fi
-
cd "$(git rev-parse --show-toplevel)"确保在项目根目录 -
--using-cache=no避免钩子中缓存路径错乱(尤其 Windows + WSL 混合环境) - 别依赖
composer run—— 它启动慢、PATH 不稳定,且钩子里 Composer 可能根本没装
真正容易被忽略的是:PHP-CS-Fixer 的规则兼容性不是向后兼容的。比如 @PSR12 在 v3.50 和 v3.60 下对 declare(strict_types=1) 的处理逻辑就不同,升级前务必先跑 composer cs:check 看 diff,而不是直接 cs:fix 再提交。



















