Composer 的 bin 字段用于声明当前包提供的 CLI 工具路径,需在 composer.json 根对象中以字符串数组形式定义,指向项目根目录下真实存在且具备可执行权限的脚本文件。

Composer 的 bin 字段不是用来“配置二进制可执行文件”的,而是声明当前包(project 或 package)提供哪些可被 composer bin 或自动符号链接调用的 CLI 工具。项目本身不靠它“生成二进制”,它只管“暴露哪个 PHP 脚本可被执行”。
bin 字段写在哪、长什么样
必须写在项目的 composer.json 根对象里,值是一个字符串数组,每个元素是相对于项目根目录的可执行脚本路径(通常为 bin/xxx 或 scripts/xxx):
{
"name": "myorg/myapp",
"bin": ["bin/myapp", "bin/myapp-worker"]
}
注意:bin 字段对 require 进来的依赖包也生效——比如你 require 了 phpunit/phpunit,它的 composer.json 里有 "bin": ["phpunit"],Composer 就会把 vendor/bin/phpunit 链向 vendor/phpunit/phpunit/phpunit。
- 路径必须真实存在,且文件需有可执行权限(Unix/macOS 下
chmod +x;Windows 下靠文件扩展名如.bat或.phar识别) - 不支持通配符或 glob,不能写
"bin": ["bin/*"] - 如果脚本是 PHP 文件,第一行建议加
#!/usr/bin/env php(非必需,但能提升跨平台兼容性)
为什么 vendor/bin 下的命令有时不更新或找不到
常见原因不是 bin 配置错了,而是 Composer 没重新生成软链接:
- 修改了
composer.json中的bin数组后,没运行composer install或composer update - 用了
composer install --no-scripts或--no-bin-links,跳过了链接步骤 - Windows 用户启用了
COMPOSER_BIN_DIR环境变量但路径含空格或特殊字符,导致链接失败(错误常为Failed to create symbolic link) - 脚本文件本身没有
#!/usr/bin/env php且无.phar后缀,在非 Linux 系统下可能无法直接执行
手动修复只需删掉 vendor/bin 并重装:rm -rf vendor/bin && composer install(Windows 用 rmdir /s vendor\bin)。
bin 脚本怎么写才真正可用
以 bin/myapp 为例,它本质就是一个 PHP CLI 入口文件,不是编译产物:
#!/usr/bin/env php
- 必须有
require到vendor/autoload.php,否则无法使用依赖中的类 - 不要依赖
__DIR__在vendor/bin下的相对位置——它实际指向的是项目根目录下的bin/xxx,所以../vendor/autoload.php是对的 - 如果想让这个脚本也能被其他项目
require使用(即作为库发布),需确保autoload配置覆盖了该脚本所在目录(例如"bin-dir": "bin"不影响自动加载,要靠"autoload": {"files": ["bin/myapp"]})
真正容易被忽略的点:bin 脚本的执行环境和 composer run-script 不同——它不自动注入 $COMPOSER_BIN_DIR,也不运行 post-autoload-dump 钩子;如果你的脚本依赖自动生成的 classmap 或 files 加载,记得先 composer dump-autoload。










