在项目中修改 bin-dir 需在 composer.json 的 config 下添加 "bin-dir": "bin",运行 composer install/update 生效;path 需手动配置才能直接调用命令;自定义脚本需声明 bin 字段并设可执行权限。

怎么在项目里改 bin-dir?直接改 composer.json
Composer 的二进制脚本默认放在 vendor/bin,但你可以把它挪到 bin、tools 或任意子目录——只要在项目根目录的 composer.json 里加一行配置就行:
{
"config": {
"bin-dir": "bin"
}
}
改完后必须运行 composer install 或 composer update 才会真正把 phpunit、phinx 这些命令链接过去。注意:bin-dir 值是相对路径(相对于项目根),不能写成 ./bin 或 /full/path(除非你明确想用绝对路径,但不推荐)。
- 目录不用提前手动创建,Composer 会自动建
- 如果项目已有
vendor/bin下的软链,改完配置后旧链接不会自动删,但新安装/更新时只往新目录写 - Windows 用户会看到
.bat文件而非符号链接,防病毒软件偶尔会拦截复制过程,遇到失败可临时禁用再试
为什么改了 bin-dir 还是不能直接敲 phpunit?PATH 没跟上
改目录只是“放哪”,不是“怎么调用”。终端不认识 phpunit,是因为系统 $PATH 里没包含你的新 bin 目录。
开发时最轻量的做法是在项目根目录执行:
export PATH="./bin:$PATH"
这样当前 shell 就能直接跑 phpunit --version。但注意:这个只对当前终端生效;重启终端就失效;IDE(比如 PHPStorm)启动时可能压根没读这行,得重启 IDE 或配它的环境变量。
- 更稳妥的长期方案是把
$(pwd)/bin写进~/.zshrc(macOS/Linux)或系统环境变量(Windows),但协作项目中不建议这么干——路径太具体,别人 clone 下来就挂 - CI/CD 脚本里别写
./bin/phpunit,统一用vendor/bin/phpunit或composer exec phpunit,后者会自动找对位置,且保证用项目锁死的 PHP 版本
自己写的命令怎么进 bin 目录?bin 字段 + 可执行权限
你想让自己的脚本(比如 bin/deploy)也出现在 bin 目录下,并被 Composer 管理,光放文件不够,还得声明。
在 composer.json 里加 bin 字段:
{
"bin": ["bin/deploy"],
"config": {
"bin-dir": "bin"
}
}
然后确保 bin/deploy 是可执行的:
- Linux/macOS:运行
chmod +x bin/deploy - 开头加 shebang,比如
#!/usr/bin/env php(PHP 脚本)或#!/bin/bash(Shell 脚本) - Windows 下可接受
.php或.bat,但推荐用.php保证跨平台一致
再跑一次 composer install,bin/deploy 就会出现在 bin/ 目录里,和 phpunit 平起平坐。
全局 bin 目录怎么查?composer global config bin-dir
如果你用 composer global require laravel/installer 装过东西,命令却报 command not found: laravel,大概率是全局 bin-dir 没进 $PATH。
先查真实路径:
composer global config bin-dir
它会输出类似 /home/you/.composer/vendor/bin 或 C:\Users\You\AppData\Roaming\Composer\vendor\bin。把这个路径加进系统 PATH,再新开终端试试。
- 别信
composer global config home—— 它只给配置目录,bin是固定子目录,得自己拼 - 升级 Composer 或重装后,这个路径一般不变,但 Windows 上 WSL 和 CMD 混用时,斜杠方向或盘符缺失可能导致 PATH 不生效,建议用双引号包住路径再加
- 改了 PATH 后,
which laravel(Linux/macOS)或where laravel(Windows)能立刻验证是否成功
真正容易被忽略的是:改 bin-dir 并不能绕过 vendor/autoload.php 的路径依赖——几乎所有命令内部都 require 它,所以哪怕你把 bin 放到 ../tools,脚本里还是得按项目结构去 autoload,硬编码相对路径八成会崩。










