bin-compat 是 Composer 用于指定 vendor/bin/ 命令包装器生成方式的配置项,决定生成 .bat、shebang 脚本还是 PHP 代理文件;Windows 用户常因 "full" 模式下 .bat 硬编码调用 php 且不处理 PATH 或含空格路径而报错。

bin-compat 是什么,为什么 Windows 用户最常被它坑
bin-compat 不是“兼容开关”,而是告诉 Composer:**你打算在什么环境下直接运行 vendor/bin/xxx 这类命令**。它决定生成哪种包装器——Unix 的 shebang 脚本、Windows 的 .bat、还是纯 PHP 代理文件。
Windows 用户最容易踩的坑是:设了 "bin-compat": "full",结果 vendor/bin/phpunit 在 CMD 里报 'php' is not recognized。这不是配置错了,而是 .bat 脚本硬编码调用 php,却没检查 PATH 或 PHP 安装路径是否含空格(比如 C:\Program Files\php\php.exe)。
真正影响执行的不是 bin-compat 值本身,而是它触发的脚本生成逻辑和后续调用方式。
三个值怎么选:full / proxy / sym(别信 auto)
auto 是 Composer 默认值,但它在 Windows 上等效 full,Linux/macOS 上尝试用符号链接(sym)——而 sym 在 Windows 下基本失效,实际仍回落到 full。所以别依赖 auto,按需显式设置:
-
full:生成.bat+ Unix 风格脚本。适合需要把项目分发给 Windows 同事、且能确保他们已将 PHP 加入 PATH 的场景。 -
proxy:只生成一个无扩展名的 PHP 代理文件(如vendor/bin/phpunit),必须用php vendor/bin/phpunit执行。跨平台最稳,CI/CD 推荐用这个。 -
sym:仅 Linux/macOS 有效,生成符号链接;Windows 下会被忽略或失败,不建议主动设。
多数现代项目(尤其用 GitHub Actions、Docker 或 WSL 开发的)应直接设 "bin-compat": "proxy",一劳永逸避开 .bat 的路径陷阱。
怎么改:项目级 vs 全局,以及重装后权限别忘
改配置不能只改composer.json 就完事,必须重装依赖才能生效:
- 项目级(推荐):
{ "config": { "bin-compat": "proxy" } }然后运行composer install或composer update - 全局(慎用):
composer config --global bin-compat proxy—— 会影响所有项目,但某些 CI 环境可能不读全局配置
注意:改完重装后,Linux/macOS/WSL 用户要手动补执行权限,否则 vendor/bin/* 仍是不可执行的:
chmod +x vendor/bin/*
Windows 用户如果用了 proxy,就不用管权限,但得习惯用 php vendor/bin/phpunit 而不是直接敲 vendor/bin/phpunit。
替代方案:vendor-bin 插件比 bin-compat 更干净
如果你只是想隔离工具(比如把phpstan 和 psalm 分开装,避免冲突),bin-compat 并非正解。该字段管的是“怎么包装”,不是“装在哪”。
- 装插件:
composer require --dev bamarni/composer-bin-plugin - 再执行:
composer bin phpstan require --dev phpstan/phpstan—— 它会把 phpstan 单独装进vendor-bin/phpstan/,不污染vendor/bin/ - 记得加
"extra": {"bin-compat": true}才能在 Windows 下生成.bat(否则只有无扩展名脚本)
这种做法绕开了 vendor/bin 的命名冲突和权限问题,也无需纠结 bin-compat 值——因为每个工具都在自己目录里,你爱用 php 直接跑还是配 alias 都行。
php --version 能跑,再调 bin-compat。










