bin-compat配置值只有"full"和"symlink",不存在"full_composer";设为"full"后生成跨平台脚本(Linux/macOS为带bootstrap的PHP脚本,Windows为调用composer.phar的.bat文件),但需确保PHP在PATH中、路径无空格且正确执行对应扩展名文件。

bin-compat 配置值只有 full 和 symlink,没有 full_composer
Composer 不识别 full_composer 这个字符串——它只接受 full 或 symlink(默认是 symlink)。如果你在 composer.json 里写了 "bin-compat": "full_composer",新版 Composer 会报 Invalid value for bin-compat,旧版则静默忽略。所谓“带完整 Composer 运行时”的脚本,就是 bin-compat="full" 模式下生成的:Linux/macOS 是带 bootstrap 的 PHP 脚本,Windows 是调用 composer.phar 或 vendor autoload 的 .bat 文件。
设了 bin-compat=full 却在 Windows 下执行失败?先确认三件事
常见现象是 vendor\bin\phpunit.bat 双击或命令行运行时报 'php' is not recognized 或 Class 'Composer\Autoload\ClassLoader' not found。这不是配置没生效,而是:
-
php命令未加入 Windows 的PATH,或路径含空格(如C:\Program Files\php),导致.bat中硬编码的php调用失败 -
bin-dir路径含中文或空格(比如"bin-dir": "my tools"),会使.bat生成语法错误(was unexpected at this time) - 你实际执行的是
vendor\bin\phpunit(无扩展名),而不是vendor\bin\phpunit.bat;CMD/PowerShell 默认不认前者 - 用了 Git Bash 或 WSL:它们不解析
.bat,此时应设bin-compat=symlink并在 Linux 环境下用vendor/bin/phpunit
自定义 bin 脚本怎么真正跨平台?靠 PHP_OS_FAMILY,不是 Composer
Composer 的 bin 字段只负责把文件复制/链接到 bin-dir,不做任何平台判断。跨平台逻辑必须由脚本自己实现:
- 入口必须是 PHP 脚本(推荐
.php后缀),开头带#!/usr/bin/env php或等效逻辑 - 在脚本内用
PHP_OS_FAMILY判断系统,再分发调用:exec('mytool-linux')、exec('mytool-win.exe')或exec('php mytool.phar') - 不要在脚本里写死
/tmp或C:\temp,改用sys_get_temp_dir() - 资源文件(如 Chromium、wkhtmltopdf)建议放
resources/下,由post-install-cmd根据系统下载或软链,而非塞进bin/
为什么 vendor/bin 总是存在,哪怕你设了 "bin-dir": "bin"?
这是 Composer 的底层机制:它始终以 vendor/bin 为中转站,再按 bin-dir 配置做二次链接或复制。所以即使你设了 "bin-dir": "bin",vendor/bin 依然有内容——Linux/macOS 是指向 ../bin/xxx 的符号链接,Windows 是复制生成的 .bat。这个中转层不能跳过,某些依赖包(尤其用自定义 install 脚本的)压根不读 bin-dir,只往 vendor/bin 写。真要绕开它,只能用 composer exec phpunit,它自动找对位置,且隔离 PHP 版本。











