不能真正替换vendor/bin,但可额外生成符号链接到自定义目录;bin-dir仅影响当前项目声明的bin脚本,依赖包脚本仍默认落vendor/bin,再软链/复制过去;终端直接调用需配置PATH或使用composer exec。

不能真正“替换”vendor/bin,但可以额外生成符号链接到自定义目录;想让终端直接识别命令,PATH 或 composer exec 才是正解。
为什么bin-dir配置看起来没生效?
常见错觉是改了 composer.json 里的 "bin-dir": "bin" 就能让 phpunit 直接出现在项目根目录的 bin/ 下——其实它只影响“当前项目自己声明的 bin”,比如你写了 "bin": ["my-tool"]。而 phpunit、psalm 这类依赖包的脚本,仍默认落到 vendor/bin/,再由 Composer 自动软链(Linux/macOS)或复制(Windows)到你设的 bin-dir 目录。
- 必须手动创建目标目录,例如
mkdir -p bin,否则composer install不报错但也不链接 - 该配置不改变
vendor/bin/的存在——它永远会被生成,删了也会回来 - Windows 下是文件复制,不是链接;路径含空格时需确保 shell 能正确解析
在 composer.json 中正确设置 bin-dir
项目级配置最安全,写在根目录 composer.json 的 config 段里即可:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
{
"config": {
"bin-dir": "tools"
}
}
- 路径必须存在且可写,
tools是相对路径,等价于$PWD/tools - Composer 2.2+ 支持
$HOME/bin这类写法,但不支持./bin或../bin - 改完后必须运行
composer install或composer update才会重建链接 - 验证是否成功:运行
ls -l tools/,看到指向vendor/bin/xxx的链接即为正常
终端里怎么才能直接敲 phpunit 就运行?
vendor/bin 默认不在系统 $PATH 里,这是环境问题,不是 Composer 配置缺陷。
- 临时加路径:
export PATH="./vendor/bin:$PATH"(当前终端有效) - 永久加路径:把上面那行加进
~/.zshrc或~/.bashrc,然后source ~/.zshrc - 更干净的做法:用
composer exec phpunit,它自动查vendor/bin/并执行,无需改 PATH - CI 脚本里别硬写
./tools/phpunit,统一用vendor/bin/phpunit或composer exec
scripts 脚本和 bin-dir 是两回事,别混用
scripts 字段定义的是 composer run xxx 命令,跟二进制文件存放位置无关。哪怕你把 bin-dir 设成 /dev/null,"scripts": {"test": "phpunit"} 依然能跑——前提是 phpunit 在 $PATH 里或 vendor/bin/ 已被加入 PATH。
- 自定义脚本调用外部命令时,优先走
$PATH,不会自动 fallback 到vendor/bin/ - 如果想确保用项目本地的
phpunit,写成"test": "vendor/bin/phpunit"或"test": "@php vendor/bin/phpunit" -
@php是 Composer 提供的快捷方式,能准确调用项目配置的 PHP 版本,比裸写php更可靠
真正容易被忽略的是:无论你怎么配 bin-dir,vendor/bin/ 始终存在、始终被写入,也始终是 Composer 内部查找命令的基准路径。所有“绕过它”的尝试,最终都得回到 PATH 或 composer exec 上——这才是设计使然,不是 bug。

















