跨项目共享依赖的本质是确保一致、可复现地引用同一份包代码,而非物理复用vendor;推荐开发用path仓库(符号链接)、生产用私有Packagist(Satis或Private Packagist),严禁共用vendor目录。

不能共用 vendor 目录,也不能靠 composer global 管理项目级依赖——跨项目共享的本质是“让多个项目能一致、可复现地引用同一份包代码”,而不是物理复用文件。
用 path 仓库做本地开发共享
这是最轻量、最可控的本地共享方式,适合团队在开发阶段快速迭代共享库。
- 共享包必须是独立目录,含自己的
composer.json(name格式为vendor/name,如myorg/logging) - 主项目中,在
composer.json的repositories下加一条:{"type": "path", "url": "../shared-logging"}(路径相对于当前项目根目录) -
require时写"myorg/logging": "*@dev",注意必须带@dev后缀,否则 Composer 不会识别本地 path 源 - 运行
composer install或update后,默认创建符号链接,改源码立刻生效;若要复制文件而非链接,加配置"options": {"symlink": false} - 该方式只应出现在开发环境,CI/CD 和生产部署必须切换为 Git 或私有 Packagist 源
用私有 Packagist(Satis / Private Packagist)做稳定分发
当共享包进入测试或上线阶段,必须脱离本地路径,走语义化版本 + 可审计的发布流程。
- Satis 是静态生成器,适合中小团队:用
satis.json列出所有 Git 仓库地址(支持 GitLab 私有库),运行satis build输出packages.json静态站点 - 主项目中声明仓库:
{"type": "composer", "url": "https://pkgs.internal.company.com"},然后require时直接写"myorg/logging": "^2.1" - Private Packagist 提供 Webhook 自动同步、权限分级、审计日志,适合多团队+高安全要求场景;它还能代理
packagist.org,统一内外源 - 关键点:所有私有包必须打 Git tag(如
v2.1.0),Satis 才能索引为稳定版本;分支名(如dev-main)只用于开发验证,不可上生产
为什么不能把 vendor 目录软链到公共位置
看似省空间,实则埋雷——autoload 路径硬编码、脚本执行冲突、lock 文件不一致都会导致运行时失败。
-
vendor/autoload.php里写死__DIR__,软链后require加载路径错乱,类找不到 - 不同项目可能启用不同插件(如
hirak/prestissimo),共用vendor会让插件状态互相污染 - 必须禁用
--no-scripts --no-plugins才能勉强跑通,但这就等于放弃自动构建、缓存清理等关键生命周期行为 - 哪怕强行统一
composer.lock和platform配置,只要有一个项目升级了 PHP 小版本,整套链路就失效
真正难的不是“怎么连”,而是“怎么让所有人装出来的结果完全一样”——这取决于你是否把包源、版本约束、平台配置、锁文件全部纳入版本控制,并在 CI 中强制校验 composer.lock 是否过期。路径和 Satis 都只是手段,一致性才是目标。











