本地安装+显式配置+Composer脚本驱动是最稳定、可复现、团队友好的方案;全局安装易引发PATH混乱、版本冲突与缓存问题,而本地安装通过vendor/bin路径、composer.lock锁版本、多项目隔离及scripts精准调用,彻底规避上述风险。

本地安装 + 显式配置 + Composer 脚本驱动,是目前最稳定、可复现、团队友好的方案。全局安装基本等于埋雷——不是不能用,而是每次换项目都得查 PATH、对版本、调缓存,纯属自找麻烦。
为什么必须本地安装 friendsofphp/php-cs-fixer
全局安装后 php-cs-fixer 命令找不到,根本原因是 Composer 的 vendor/bin 没进系统 PATH;硬加又会导致多项目版本冲突。本地安装则完全规避这些问题:
- 二进制路径确定:
vendor/bin/php-cs-fixer(Linux/macOS)或vendor\bin\php-cs-fixer.bat(Windows) - 版本锁死在
composer.lock里,CI/CD 直接复现,无需额外 setup - 不同项目可共存 v3.52 和 v3.58,互不干扰
-
composer require --dev friendsofphp/php-cs-fixer执行完就能用,不用改环境变量
php-cs-fixer fix 不生效的常见原因
直接运行 vendor/bin/php-cs-fixer fix 却没任何文件被修改?大概率踩了这几个坑:
- 没加
--dry-run或--diff:v3 默认就是--dry-run模式,只检查不写入,必须显式加--write或去掉--dry-run才会真正保存 - 没指定目录:默认只扫描当前目录下的
.php文件,想处理src/和tests/,得写成vendor/bin/php-cs-fixer fix src/ tests/ - 规则文件名错了:必须是
.php-cs-fixer.php(开头带点),不是.php_cs、php-cs-fixer.php或config.php - 配置里漏了
setFinder():没定义扫描范围,工具可能什么也不做,或者误扫vendor/目录
如何让 composer format 真正可用
在 composer.json 的 scripts 里配命令,关键不是“能跑”,而是“跑得准、不翻车”:
立即学习“PHP免费学习笔记(深入)”;
- 显式指定配置文件:
"format": "php-cs-fixer fix --config=.php-cs-fixer.php --verbose",避免加载默认规则(它随版本变,极不稳定) - CI 场景用
"check-style": "php-cs-fixer fix --config=.php-cs-fixer.php --dry-run --diff --using-cache=no",禁用缓存确保每次检查一致 - 别写
vendor/bin/php-cs-fixer:Composer 自动把bin-dir加进当前进程 PATH,直接写php-cs-fixer更干净 - 加
--verbose:出错时能看到具体哪个文件、哪条规则失败,比静默退出好调试得多
Git pre-commit 钩子怎么写才不卡提交
钩子不是越重越好,重点是快、稳、可跳过:
- 用
composer run cs:check(对应--dry-run --diff)做预检,有差异就中断提交,不格式化——把修复动作留给开发者手动执行composer format - 避免在钩子里直接
fix:自动改代码再提交,容易掩盖真实变更,Code Review 时看 diff 就乱了 - 加判断跳过:比如
git diff --cached --quiet || exit 0,没暂存文件就直接过,不浪费时间 - 缓存文件必须设:
setCacheFile('.php-cs-fixer.cache'),否则大项目每次 pre-commit 都全量扫描,几秒起步
最易被忽略的是配置文件里的 setFinder() —— 它不光决定修哪,还决定不修哪。漏掉 ->exclude('vendor') 或 ->notName('*.blade.php'),一次 composer format 可能把你依赖包里的文件也顺手“修复”了,而且 Git 还真会把它当改动提交上去。



















