Composer 不会自动让终端直接运行 mytool,需将 vendor/bin 加入 $PATH 且脚本满足三条件:存在、有 shebang、chmod +x;bin 字段须为相对路径,如 "bin/mytool"。

直接说结论:Composer 不会自动让你在终端敲 mytool 就运行,它只负责把脚本软链接进 vendor/bin/(或你自定义的 bin-dir),能不能直接调用,取决于你有没有把那个目录加进 $PATH,以及脚本本身是否合规。
怎么让自己的脚本进 vendor/bin
核心是三件事同时满足:脚本存在、有可执行权限、composer.json 里正确声明 bin 字段。
-
bin字段值必须是项目根目录下的**相对路径**,比如"bin": ["bin/mytool"],对应文件./bin/mytool - 脚本第一行必须带 shebang:
#!/usr/bin/env php(PHP 脚本)或#!/usr/bin/env sh(Shell 脚本) - Linux/macOS 下必须设执行权限:
chmod +x bin/mytool;Windows 下可接受.php后缀,Composer 会自动加php前缀调用 - 别写错路径:比如脚本在
src/Console/MyTool.php,但它是类文件,不是 CLI 入口——得另建一个bin/mytool文件去require它
vendor/bin 没生成链接?先查这几个地方
常见现象是运行 composer install 后,vendor/bin/ 下空空如也。这不是 Composer 失效,而是配置或环境没对上。
- 确认依赖包(或你自己项目的
composer.json)里真写了"bin": [...],且数组里每个路径都指向真实存在的文件 - 检查是否用了
composer create-project—— 它有时跳过bin链接,补跑一次composer install --no-dev或删掉vendor重装 - 如果改过
config.bin-dir,必须重新运行composer install才生效;旧链接不会自动清理,新目录也不会自动创建 - 运行
composer config bin-dir看当前生效的路径,再ls -l $(composer config bin-dir)确认链接是否存在
想直接敲命令就运行?PATH 是关键
vendor/bin/ 默认不在系统 $PATH 里,所以 phpunit 报 command not found 是常态,不是 bug。
- 临时方案:在项目根目录下运行
export PATH="./vendor/bin:$PATH"(注意是./vendor/bin,不是vendor/bin) - 长期方案:把这行加进
~/.zshrc或~/.bashrc,然后source ~/.zshrc;但不推荐用于协作项目,容易污染其他项目环境 - 更稳妥的协作做法:用
composer scripts封装,比如"scripts": {"mytool": "bin/mytool"},然后统一用composer run mytool调用,保证走项目锁定的 PHP 版本和 autoloader - CI/CD 中建议用全路径调用:
./vendor/bin/mytool --version,避免 PATH 配置差异
自定义 bin 目录位置(比如改成 ./bin)
不想用默认的 vendor/bin?可以改,但要注意影响范围。
- 在
composer.json的config段加:"bin-dir": "bin",路径是相对于项目根目录的 - 改完必须运行
composer install或composer update,否则链接不会重建,旧目录也不会被清空 - 所有依赖包中声明的
bin脚本(比如phpunit、psalm)都会被链入这个新目录,不只是你自己的 - 如果你同时设了
"bin": ["bin/mytool"]和"bin-dir": "bin",最终效果是bin/mytool→bin/mytool(即原地链接),实际还是得靠PATH或全路径调用
最容易被忽略的一点:shebang 行和执行权限是硬性要求,不是可选项。哪怕脚本逻辑完全正确,缺了 #!/usr/bin/env php 或忘了 chmod +x,Composer 就当它不存在——不会报错,也不会链接,静默跳过。











