唯一可靠方案是path仓库:需在主项目composer.json中配置相对路径repositories,本地包composer.json必须声明"options": {"symlink": true}且name严格匹配,改autoload后须手动执行composer dump-autoload -o。

path仓库是唯一可靠方式
想让多个项目共用一个本地包,别碰composer link——它只对已安装包生效、不写lock、不更新autoload,CI里一跑就断。真正可协作、可复现的方案只有path类型仓库。
主项目composer.json里加repositories块,url必须是相对路径(比如"../shared-packages/my-utils"),不能带~或绝对路径;目标目录下必须有合法composer.json,且name字段要和require中写的**逐字一致**(大小写、斜杠、vendor名全得对上)。
- 首次引入必须运行
composer update vendor/name,不是install——因为install只读composer.lock,根本不解析repositories - 要热更新代码(改源码立刻生效),得在本地包自己的
composer.json里加"options": {"symlink": true},主项目配置options无效 - Windows用户需开启“开发者模式”或以管理员身份运行终端,否则
symlink会静默退化为复制
共享包的composer.json必须自己控制symlink
是否走软链,决定权不在主项目,而在被引用的那个本地包。它的composer.json里必须显式声明"options": {"symlink": true},否则即使主项目配了path,vendor/下还是个副本,改代码不生效。
这个设置不会被composer install覆盖,但composer update vendor/name会重新应用它。验证是否成功:Linux/macOS下ls -la vendor/vendor/name应看到->指向源目录;Windows下dir vendorendor
ame应显示“快捷方式”类型。
- 如果改了本地包的
autoload映射(比如新增PSR-4命名空间),必须手动执行composer dump-autoload -o刷新主项目的自动加载器 -
composer update后发现软链没了?大概率是本地包composer.json里漏了options,或者name拼错了
团队协作时路径必须真实存在且相对
CI流水线或新同事拉代码后vendor里没模块?八成是url路径写成了"${HOME}/xxx"或"../shared"这种跨项目路径——Composer不展开环境变量,也不做路径校验,只是静默跳过该仓库,然后去Packagist找包,最后报Could not find package。
正确做法是把共享包放在所有项目都能访问的固定位置,比如统一放在../shared-packages/,然后每个主项目都用"url": "../shared-packages/my-pkg"。CI脚本里得提前mkdir -p ../shared-packages并确保权限可读。
- 如果共享包只用于开发调试,必须放在
require-dev里,但CI默认跑composer install --no-dev,这时它根本不会装——要么CI加--dev,要么把它挪到require - 别指望
config.vendor-dir能解决多项目共享——它只能设一个全局路径,且不支持按包分目录,强行改会导致autoload失效、bin命令找不到
autoload变更后必须手动dump
哪怕软链已经建好,只要本地包的composer.json里改了autoload(比如新增"MyApp\Helper\": "helpers/"),主项目vendor/autoload.php就不会认这些新类——Composer不会自动重生成映射。
必须回到主项目根目录,执行composer dump-autoload -o。不加-o也能用,但优化后的自动加载器更快、更准,尤其对大型共享包。
- 这个动作和
composer update无关,也和install无关,是独立步骤 - 如果用了
psr-4但类文件没出现在预期路径下,dump-autoload也不会报错,只会默默忽略——先确认文件结构是否匹配映射规则


















