Composer脚本调用vendor/bin二进制文件需在composer.json的"scripts"中写相对路径命令,如"test": "vendor/bin/phpunit",而非exec;必须确保bin文件存在、有执行权限、PHP环境匹配,且不依赖PATH。

Composer脚本怎么调用 vendor/bin 下的二进制文件?
直接在 composer.json 的 "scripts" 里写 exec 命令是错的——Composer 不识别 exec,它只认 shell 命令字符串,且默认在项目根目录执行。想运行 vendor/bin/phpunit 或 vendor/bin/psalm,得确保路径可访问、权限正常、PHP 环境匹配。
常见错误现象:sh: 1: phpunit: not found 或 Permission denied,本质是 PATH 未包含 vendor/bin,或二进制文件没加执行权限(尤其 Windows WSL 或某些 CI 环境)。
- 始终用相对路径调用:
"test": "vendor/bin/phpunit",不依赖 PATH - Windows 用户注意:Composer 在 Windows 上默认用 cmd 执行,
vendor/bin/*是 .bat 文件,但部分包(如 Laravel Pint)生成的是 Unix shell 脚本,需启用 Git Bash 或配置COMPOSER_BIN_DIR - 如果脚本需要传参(比如
--filter),直接拼在命令后:"test:unit": "vendor/bin/phpunit --filter=Unit"
为什么 vendor/bin 下的文件有时“不存在”或无法执行?
vendor/bin 是 Composer 的符号链接目录(或复制目录),由 bin-dir 配置和包的 bin 字段共同决定。不是所有包都声明了 bin,也不是所有二进制都默认可执行。
典型问题场景:本地开发能跑,CI 失败;或者 composer install --no-dev 后脚本突然报错。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 检查目标包是否真有
"bin"字段(看其composer.json),例如phpunit/phpunit有"bin": ["phpunit"],而monolog/monolog没有 - 确认是否安装了
dev依赖:phpunit默认在require-dev,--no-dev会跳过安装,导致vendor/bin/phpunit根本不生成 - Linux/macOS 下,若手动改过
vendor权限或用了 rsync 同步,可能丢失执行位:可临时修复chmod +x vendor/bin/*(但不推荐进 git,应查清源头)
如何让自定义扩展包暴露自己的 CLI 工具?
如果你在写一个 Composer 包,并希望用户能通过 vendor/bin/mytool 直接调用,关键不在“暴露”,而在“声明”和“可执行性”。Composer 只做两件事:读 bin 字段、把对应文件软链(或复制)到 bin-dir。
不要试图在包里写个 exec 函数去“注册”命令——那没用。用户调用的是文件,不是 PHP 函数。
- 在你包的
composer.json中添加:"bin": ["bin/mytool"](路径相对于包根目录) - 确保
bin/mytool是可执行脚本:首行必须是#!/usr/bin/env php,且有执行权限(chmod +x bin/mytool) - 脚本内容建议用
#!/usr/bin/env php开头,而非硬编码/usr/bin/php,避免不同环境 PHP 路径差异 - 如果工具需加载 Composer 自动加载器,脚本内要显式 require:
require __DIR__.'/../vendor/autoload.php';(注意路径偏移)
“运行 Vendor 二进制”时最常被忽略的兼容性点
看似只是敲一行命令,但实际横跨了 Composer 配置、OS 执行环境、PHP SAPI 模式、甚至容器镜像基础层。最容易被跳过的,是 shebang 行与解释器的实际匹配。
- Mac/Linux 上,
#!/usr/bin/env php依赖系统 PATH 找php,而 CI 镜像(如php:8.2-cli)里可能只有php8.2,没有php别名——此时脚本静默失败或报command not found - 某些共享主机禁用
shell_exec,导致即使命令写对,Composer 脚本也卡住无输出(表现为 hang,非报错) - PHP-FPM 环境下执行 Composer 脚本(比如通过 Web 触发),
$_SERVER['PATH']往往极简,vendor/bin不在其中,必须绝对路径调用
复杂点从来不在“怎么写”,而在“谁在什么上下文里执行它”。每次怀疑脚本不工作,先 echo $PATH && which php && ls -l vendor/bin/xxx —— 三行 shell 比重读文档快得多。

















