本地包 version 字段必须显式声明且与主项目 require 的版本字符串严格匹配,如"dev-main"对应"my-vendor/my-package": "dev-main";改 version 后需运行 composer update my-vendor/my-package 才生效。

本地 Composer 包的版本号不是“写完就生效”的静态字段,它直接决定 composer require 能否解析、composer update 是否命中、以及 vendor 目录里是软链接还是复制体——调试必须围绕 composer.json 中的 version 字段和依赖声明的匹配逻辑展开。
本地包的 version 字段怎么写才被识别?
Composer 不从 Git 分支或 tag 自动推断本地 path 仓库的版本,它只读取包目录下 composer.json 的 version 字段。这个值必须显式声明,且格式需与你在主项目中写的版本约束严格一致。
- 合法写法:
"version": "dev-main"(对应"my-vendor/my-package": "dev-main") - 合法写法:
"version": "1.0.x-dev"(对应"my-vendor/my-package": "1.0.x-dev") - 错误写法:
"version": "main"(缺少dev-前缀,Composer 不认) - 错误写法:
"version": "dev-master"(但包里根本没有master分支,Git 检出失败) - 注意:Windows 下路径不区分大小写,但
version字符串仍需完全匹配,比如"dev-Main"≠"dev-main"
composer require 时该用什么版本字符串?
path 类型仓库不走语义化版本解析,所以不能写 "^1.0" 或 "1.0.0"。你必须用包 composer.json 里 version 字段的**完整原始值**,或其等效别名(如 dev-main → dev-main,不可简写为 main)。
- 如果本地包
composer.json是"version": "dev-main",主项目就得写"my-vendor/my-package": "dev-main" - 如果本地包
composer.json是"version": "2.3.0-beta2",主项目就得写"my-vendor/my-package": "2.3.0-beta2"(且要配"minimum-stability": "beta") - 写错会报
Could not find a matching version,而不是 “找不到包”——说明仓库识别成功,但版本不匹配 - 运行
composer show my-vendor/my-package可确认当前解析到的 version 值,用于比对
改了本地包 version 后为什么 vendor 没更新?
因为 Composer 对 path 仓库默认做硬链接(Linux/macOS)或完整复制(Windows),它不会自动监听 version 变更。你改了本地包的 composer.json,必须手动触发重映射,否则 vendor 里仍是旧链接或旧副本。
- 推荐:运行
composer update my-vendor/my-package(只更新指定包,安全) - 备选:运行
composer dump-autoload(仅刷新自动加载,不更新文件结构) - 危险操作:删
vendor/+composer.lock再install—— 这会让 Composer 把本地包当作普通源码复制进 vendor,失去“改即生效”的调试意义 - 验证是否生效:进
vendor/my-vendor/my-package,执行ls -l(Unix)看是否为软链接;或检查文件修改时间是否与本地包目录一致
为什么 composer link 不适合调试版本号?
composer link 是给**已安装包**做的软链接命令,它完全绕过 version 字段校验,也不读取本地包 composer.json 的 version。它只认已安装的包名,然后强行指向你当前所在目录——这会导致两个关键问题:
- 它不更新
composer.lock,后续composer update会把链接覆盖回正常安装态 - 它不校验
autoload规则是否匹配,容易因命名空间或 PSR-4 配置不一致导致类找不到 - 它无法测试“不同
version字符串能否被正确解析”这个核心调试点 - 真正需要调试版本号匹配逻辑时,
composer link是干扰项,应禁用或卸载相关插件
版本号调试的本质是验证“声明—解析—映射”三步闭环:本地包写了什么 version,主项目 require 时写了什么字符串,Composer 是否按预期生成了链接或副本。任何跳过其中一环的操作(比如只改代码不改 version、只改 require 不更新 lock、依赖 link 绕过校验)都会让调试失效。











