Windows下bin-compat设为full会生成.bat文件,因其硬编码调用php导致PATH缺失或PHP路径含空格时执行失败,推荐统一使用php vendor/bin/xxx绕过包装器。

Windows下bin-compat设为full会生成.bat文件
Composer默认在Windows上把bin-compat设为full,这意味着它不仅生成可执行的.bat包装脚本,还会尝试生成.exe代理(通过bin/compile机制)。这些.bat脚本本质是调用php.exe执行对应PHP脚本,路径硬编码或依赖PATH中的PHP。若你本地PHP不在PATH里,或者用了WSL、Docker等混合环境,运行vendor/bin/phpunit这类命令就会报'php' is not recognized as an internal or external command。
-
bin-compat = full→ 生成vendor/bin/phpunit.bat+vendor/bin/phpunit(Unix风格符号链接或空文件) -
bin-compat = sym→ 只生成符号链接(Windows不支持,实际退化为复制或失败) -
bin-compat = auto(默认)→ Windows下等效full,Unix-like系统用sym
vendor/bin/xxx在CMD/PowerShell里执行失败的常见原因
不是bin-compat本身出错,而是它生成的.bat脚本对环境假设太强。比如vendor/bin/phpunit.bat开头通常是:
@ECHO OFF php "%~dp0/../phpunit/phpunit/phpunit" %*
这里直接调用php,没检查是否存在,也没用绝对路径。一旦你的PHP安装路径含空格(如C:\Program Files\php\php.exe),或PHP未加入PATH,脚本就崩。PowerShell默认还禁用.bat执行策略,需手动启用Set-ExecutionPolicy RemoteSigned -Scope CurrentUser(但这是PowerShell策略,和.bat无关,容易混淆)。
- 错误现象:
The system cannot find the path specified.或php is not recognized - 临时修复:把PHP目录加进
PATH,或改用php vendor/bin/phpunit绕过.bat - 根本规避:在
composer.json里显式设"config": {"bin-compat": "sym"},再composer install重装——但Windows下sym基本无效,最终仍回落到full
用php -d或alias绕过.bat的实操建议
与其纠结bin-compat配置,不如控制执行入口。Windows用户真正需要的是稳定调用,而不是依赖Composer生成的包装器。
- 统一用
php vendor/bin/phpunit:跳过.bat,直连PHP解释器,路径安全,兼容所有PHP版本 - PowerShell中加函数别名:
function phpunit { php vendor/bin/phpunit @args },之后可直接敲phpunit --version - VS Code终端或Git Bash中,用
alias phpunit='php vendor/bin/phpunit'(写入~/.bashrc) - 避免在
composer.json的scripts里写"test": "vendor/bin/phpunit",改写成"test": "php vendor/bin/phpunit"
WSL用户尤其要注意bin-compat的双重陷阱
你在WSL里跑composer install,但vendor/bin里的.bat文件会被一并写入(因为Composer检测宿主是Windows)。结果:WSL中./vendor/bin/phpunit执行失败(权限+换行符+CRLF问题),而php vendor/bin/phpunit又可能因路径指向Windows下的php.exe而报错。这时bin-compat不再是便利,而是污染源。
- WSL开发时,务必在
composer.json中强制设"bin-compat": "sym",并确保composer install在WSL环境下执行(非Windows CMD) - Git for Windows的Bash(MinTTY)同理:它模拟Unix环境,但
.bat文件依然存在且不可执行 - CI/CD中(如GitHub Actions Windows runner),
bin-compat行为一致,但可通过shell: pwsh或shell: cmd显式控制执行上下文
bin-compat的值,而是你是否意识到:Windows下vendor/bin/xxx只是个脆弱的中间层,它不处理PHP路径、不校验权限、不区分环境。绕过它,比调试它更省时间。










