必须为每个项目使用独立 vendor 目录,禁用 composer global require;全局安装会导致版本冲突、autoload 失效、CI/CD 不稳定;composer install 必须在项目根目录运行;复用私有包应通过 path 仓库或私有 Packagist,上线前需移除 path 配置;务必提交 composer.lock 以保证依赖一致性。

每个项目必须用独立的 vendor 目录,不能共用全局依赖 —— 这是 Composer 多项目隔离的铁律。
为什么不能用 composer global require 管理项目依赖
全局安装的包(如 larastan、phpunit)会装进 ~/.composer/vendor/,所有项目共享同一份代码和版本。一旦某个项目需要 phpunit ^9.5,另一个要 ^10.4,立刻冲突。更麻烦的是,autoload 机制不会自动加载全局 vendor,你在项目里 use PHPUnit\Framework\TestCase 会直接报错。
- 全局命令(如
phpunit)只是可执行脚本入口,不等于项目能用其类库 -
composer global的autoload.php不参与项目自动加载链 - CI/CD 构建时,全局环境不可控,极易失败
composer install 必须在项目根目录运行
Composer 通过当前目录下的 composer.json 和 composer.lock 决定装什么、装哪、怎么 autoload。跨目录执行(比如从父文件夹运行 composer install --working-dir=project-a)虽可行,但容易误读路径、混淆 autoloader 映射,尤其涉及 path 类型仓库或 repositories 配置时。
- 始终
cd project-a && composer install,拒绝“图省事”式操作 -
composer install不带--no-dev时,会装require-dev,上线前务必确认是否需要 - 若
vendor已存在但composer.lock更新过,必须重新install(而非update),否则版本不一致
如何安全地复用私有包(不破坏项目隔离)
多个项目依赖同一个内部 SDK 或组件时,不能把包代码直接拷进各项目 vendor,也不能改 composer.json 的 require 为 "myorg/sdk": "dev-main" 后硬 push 到 Packagist。正确做法是用 path 仓库 + 本地开发链接,或私有 Packagist(如 Satis、Private Packagist)。
- 开发阶段:在项目
composer.json中加"repositories"指向本地路径:"repositories": [ { "type": "path", "url": "../myorg-sdk" } ]然后composer require myorg/sdk:dev-main - 上线前必须删掉
path仓库配置,改用真实私有源或 tag 版本,否则部署到服务器会找不到包 -
composer update时加--with-dependencies可避免子依赖被意外降级
最常被忽略的一点:`.gitignore` 里写 /vendor 是对的,但很多人忘了检查 composer.lock 是否已提交 —— 它才是多项目间依赖一致性的唯一事实来源。没它,composer install 就退化成 composer update,结果不可重现。










