必须用dev-分支名而不能写版本号:Composer path仓库完全忽略本地composer.json中的version字段,仅依据Git HEAD所在分支名匹配require中的dev-main等格式,且要求本地目录已git init并有commit,repositories必须置于主项目composer.json顶层,否则静默失败。

path仓库里必须用dev-分支名,不能写版本号
本地包走path类型仓库时,Composer根本不会读取composer.json里的version字段。它只看Git分支名,并强制要求你在require中使用dev-main、dev-develop这类形式——哪怕你本地composer.json写了"version": "1.2.3",composer require vendor/name:1.2.3也会报Could not find a matching version of package。
常见错误现象:本地包在main分支,composer.json里name和路径都对,但require写成"vendor/name": "^1.0"或"vendor/name": "1.2.3",结果始终失败。
-
require字段必须显式写"vendor/name": "dev-main"(分支名需与当前Git HEAD一致) - 本地包目录必须已执行
git init且至少有一个commit,否则Composer直接跳过该路径 - 如果要用
dev-develop,确保Git当前分支名就是develop,不是dev或feature/foo
为什么require写对了还是“Could not find package”
根本原因不是网络或权限问题,而是Composer压根没扫描到你的本地目录。它只从主项目composer.json根级的repositories数组里找源,而这个数组经常被错放位置。
典型配置错误:
-
repositories写在了本地包自己的composer.json里,而不是主项目的 -
repositories被塞进了config、extra或require字段,完全不生效 -
url用了file://前缀、~/或环境变量,应改用"./packages/my-pkg"这类相对路径 - Windows下路径用了反斜杠
\又没转义,建议统一用/
验证是否加载成功:运行composer config --list | grep repositories,能看到你配的path条目才算真正生效。
改完本地代码,主项目里为什么没更新
默认行为是复制(copy),不是符号链接(symlink)。改本地包代码后,主项目vendor/里还是旧文件,因为Composer没重新拉取。
关键操作只有两步:
- 在
repositories条目中加"options": {"symlink": true}(Windows必须显式写,且命令行需以管理员权限运行) - 执行
composer update vendor/name,不是install——install只重建缺失链接,update才会刷新已有链接的目标
验证是否成功:
Linux/macOS:运行ls -la vendor/vendor/name,输出里应有->指向你的源目录
Windows:运行dir vendor\vendor\name,应显示为“快捷方式”类型
platform配置对path包没影响,别白费劲
config.platform和--platform参数只影响远程包的依赖解析,对path仓库下的包完全无效。因为path模式跳过所有元数据请求,直接读取本地composer.json,根本不经过版本约束校验流程。
所以如果你在path包里写了"require": {"php": "^8.2"},而主项目platform设的是php:8.1,Composer照样装——它只认本地Git分支名,不检查PHP兼容性。
真正要控制PHP版本兼容,得靠:
- 本地包自己的composer.json里写"config": {"platform": {"php": "8.1.0"}}(仅影响该包内部依赖)
- 或者主项目CI脚本里用composer install --platform=php:8.1.0(但只对远程包起作用)
最易忽略的一点:path仓库的脆弱性来自它的“直读”特性——没有Packagist兜底,拼错一个name、少一个commit、多一个空格,就静默失败,连错误提示都不给。


















