composer 不生成代码也不校验 psr-12,仅负责装包;psr-12 兼容需组合 php-cs-fixer 等工具链,模板项目多滞后于 2019 年定稿的标准,须手动配置规则并警惕格式化引发的测试失效。

Composer 本身不生成代码,也不校验 PSR-12;它只管装包。想快速产出合规类库,得靠组合工具链,不是靠 composer create-project 按个按钮就完事。
用 composer create-project 初始化骨架时,为什么默认不 PSR-12?
因为 Composer 的模板项目(比如 php-library-skeleton)大多停留在 PSR-2 或干脆没约束。PSR-12 是 2019 年才定稿的,很多老模板没更新,而且“标准”这事没法靠 composer.json 自动注入到源码里。
常见错误现象:composer create-project vendor/skeleton 后跑 phpcs 直接报十几处 PSR12.Classes.ClassDeclaration 错误——类花括号换行、public 前空格、方法间空行数都不对。
- 别指望模板自带 PSR-12 兼容,先查它的
phpcs.xml或.php-cs-fixer.dist.php是否存在且启用psr12规则集 - 优先选明确声明支持 PSR-12 的骨架,比如
php-mock/php-mock-phpunit-skeleton(带预置php-cs-fixer配置) - 如果骨架没配好,立刻删掉
src/下自动生成的类,手写或用 IDE 生成——现代 PHPStorm 新建类时可设“PSR-12 模板”,比依赖模板更可靠
本地强制 PSR-12 的最小可行配置:php-cs-fixer + composer script
不用装全局工具,也不用改 IDE 设置,靠 composer.json 绑定就能让所有人(包括 CI)统一格式。
使用场景:新项目初始化后第一件事就是加格式化守门员,避免队友提交不一致代码。
- 运行
composer require --dev friendsofphp/php-cs-fixer - 在
composer.json的"scripts"里加:"fix": "php-cs-fixer fix --rules=@PSR12 --using-cache=false" - 加
--using-cache=false是为了防止 CI 环境因缓存路径问题跳过修复(尤其 Docker 容器里) - 执行
composer fix后会直接重写src/和tests/下所有 PHP 文件,注意提前 commit 当前修改
phpcs 报 PSR12.Methods.MethodDeclaration 但 php-cs-fixer 不修?
因为两个工具规则粒度不同:php-cs-fixer 默认启用的 @PSR12 规则集其实略保守,比如它不强制函数参数每行一个(PSR-12 允许单行多参数),而 phpcs 的 Squiz.WhiteSpace.FunctionSpacing 类规则更细。
性能影响:同时装 phpcs 和 php-cs-fixer 会多占 20MB 依赖,但开发机上几乎无感;CI 中建议只保留 php-cs-fixer --dry-run 做检查,省去 phpcs 解析开销。
- 若要严格对齐
phpcs的 PSR-12 判定,改用php-cs-fixer的完整规则数组:--rules='{"psr12":true,"method_argument_space":{"keep_multiple_spaces_after_comma":false}} - 别把
phpcs当修复工具用——它只报错,不改代码;phpcbf才是它的自动修复兄弟,但兼容性不如php-cs-fixer - 检查是否误启了
Squiz标准:PSR-12 是独立标准,phpcs -i输出里看到Squiz就说明配置混用了,得清掉phpcs.xml里的非 PSR 规则
真正卡住人的地方不是工具不会装,而是第一次跑 composer fix 后发现 composer test 失败了——因为 PSR-12 调整了 use 语句顺序、移除了多余空行,导致某些测试里用 ReflectionClass 读取 docblock 的逻辑崩了。这种边界情况,得手动看 diff,不能无脑信任格式化结果。










