根本原因是全局bin目录未加入系统PATH,导致shell无法定位可执行文件;项目内安装的工具因未入PATH而不可直接调用,这是Composer为保障隔离性所做的主动设计。

全局安装的命令找不到,不是没装成功,而是系统根本没去那个目录找;项目里装的包不能直接敲命令运行,也不是 bug,是 Composer 故意隔离出来的行为。
为什么 composer global require laravel/installer 后 laravel 命令报 command not found
根本原因:Composer 把可执行文件放到了 ~/.composer/vendor/bin(Linux/macOS)或 %APPDATA%\Composer\vendor\bin(Windows),但这个路径不在系统 PATH 里。
- Linux/macOS:在
~/.zshrc或~/.bashrc末尾加export PATH="$HOME/.composer/vendor/bin:$PATH",然后运行source ~/.zshrc - Windows:打开「系统属性 → 高级 → 环境变量」,把
%APPDATA%\Composer\vendor\bin加进「用户变量」的PATH,必须重启终端(关掉再开不算,要新建一个) - 验证是否生效:
echo $PATH或echo %PATH%看输出里有没有对应路径;再试which laravel或where laravel
为什么项目里 composer require phpunit/phpunit 后,phpunit 命令不能直接用
因为它的二进制只存在于当前项目的 vendor/bin/phpunit,没进 PATH,系统自然不认识。这不是缺陷,是设计原则:项目边界必须清晰。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 正确调用方式:
./vendor/bin/phpunit(Linux/macOS)或vendor\bin\phpunit(Windows) - 想简化?在
composer.json的scripts字段加一行:"test": "php vendor/bin/phpunit",之后直接运行composer test - 别手动建软链或改全局
PATH指向某个项目的vendor/bin——CI 会挂,同事拉代码也跑不起来
哪些该全局装,哪些死都不能全局装
判断标准不是“是不是工具”,而是“它参不参与项目运行逻辑”。一句话:工具装全局,依赖装项目。
- ✅ 推荐全局:
laravel/installer、friendsofphp/php-cs-fixer、phpstan/phpstan——只在你敲命令时起作用,不被autoload加载,不上生产 - ✅ 必须项目内:
guzzlehttp/guzzle、monolog/monolog、symfony/console——会被代码new或use,必须进composer.lock,必须上生产 - ⚠️ 特别注意:
phpunit/phpunit表面是工具,但常被tests/bootstrap.php或phpunit.xml显式引用,CI 流水线也依赖具体版本,所以更推荐项目内装 - ❌ 绝对禁止全局:
doctrine/dbal、laravel/framework——等于让composer.lock失效,部署时类找不到、版本错乱、错误信息指向你根本没装过的类
全局和项目都装了同一个包,为什么报 Class 'Symfony\Component\Console\Application'
这是 autoload 冲突的典型表现:全局包和项目包可能加载了不同版本的 symfony/console,而 Composer 的自动加载器无法区分来源,最终加载了不兼容的类定义。
- 常见于同时全局装了
php-cs-fixer和项目里用了symfony/consolev6+ 的情况 - 解决方法不是卸一个,而是确保项目依赖声明明确,且避免在项目中
require-dev引入与全局工具同源的组件(比如不要在项目里require symfony/console来写 CLI 命令,改用symfony/console的稳定子集或封装) - 真正难排查的点在于:错误不总在首次运行出现,而是在某些 autoloader cache 生效后才爆发,且本地能跑、CI 报错

















