答案是严格按规则配置:repositories中声明type为"path"且url指向含合法composer.json的目录,其name与require完全一致,本地需git初始化并存在对应dev分支,且minimum-stability需支持dev版本。

Composer 配置本地 path 仓库不是“加个配置就能用”,它是一套有明确匹配规则、严格校验顺序、且行为可被系统权限和更新策略影响的链路。不按逻辑走,composer require 就会报 Could not find a matching version of package vendor/name,而你本地目录明明就在那儿。
怎么让 Composer 看到你的本地包
它不扫描硬盘,也不猜路径——只认你明文写在项目根 composer.json 的 repositories 字段里的一条声明:
-
type必须是"path",不能是"package"或漏写 -
url必须指向一个**目录**(如"./packages/my-utils"),不是composer.json文件本身,也不能带file://前缀 - 该目录下必须存在合法的
composer.json,且含name(如"myorg/utils")和version(哪怕写"dev-main") - 如果用了通配符(如
"../packages/*"),每个子目录都得有独立的composer.json,否则整个通配条目被跳过
为什么 composer require vendor/name 总失败
错误不是网络或缓存导致的,而是三处对不上:
- 你在
require写的包名(如"myorg/utils")和本地包composer.json里的name字段**字面完全不一致**(大小写、vendor 名、斜杠方向都敏感) - 本地包没 Git 初始化,或没任何 commit:Composer 拒绝加载空仓库,
git init && git commit --allow-empty -m "init"是最低要求 - 版本约束写错了:
path类型默认只认dev-开头的分支名,"*"、"^1.0"、"1.0.0"都不匹配;应写"dev-main"或"dev-develop",并确保本地 Git 分支名与之对应 - 项目
composer.json没设"minimum-stability": "dev",又没在 require 后加@dev,导致dev-main被稳定性策略过滤掉
vendor/ 下为什么是符号链接,以及怎么让它生效
这是 path 类型的默认行为,但依赖两个前提:
- 操作系统支持软链:Linux/macOS 默认 OK;Windows 需开启开发者模式,或以管理员身份运行终端(否则自动 fallback 到复制)
- 本地包未被标记为
"dist"类型(即没在composer.json中设"type": "library"并配合"dist"字段)
验证是否成功:运行 ls -la vendor/vendor/name(macOS/Linux)或 dir vendor\vendor\name(Windows),输出中应含 -> 或 <symlink></symlink>。改本地代码后,项目里立刻可见效果——这和 composer dump-autoload 无关,后者只刷新类映射。
改了本地包代码,为什么 composer install 不更新链接
composer install 只补缺失链接,不重解析已有链接的目标。它完全信任 composer.lock 里记录的路径和版本。所以:
- 改完本地包代码后,必须运行
composer update vendor/name才会重新读取path目录下的composer.json,重建 symlink - 不要用无参数的
composer update,它会全量重算依赖图,可能意外升级其他包 - CI/CD 环境下,
path仓库必然失效(路径不存在),上线前必须从repositories中移除该条目,否则构建失败 - 若 symlink 失效(比如 IDE 重命名父目录),
composer update不会自动修复旧链接,需先手动删掉vendor/vendor/name,再运行update
最常被忽略的是:路径声明、name 字段、Git 分支名、require 版本约束这四者必须字面一致,缺一不可;而 symlink 的生命周期完全由 update 控制,install 对它毫无感知。











