Composer 支持通过 type: "package" 仓库类型引用本地 ZIP 文件,需手动声明包名、版本、dist(含 file:// 绝对路径或相对路径)、autoload 等元信息;ZIP 结构须扁平,避免外层目录;修改 ZIP 后需手动清理 vendor 和 lock 文件并执行 composer update 刷新。

直接在 composer.json 中用 package 仓库类型引用本地 ZIP
Composer 本身不支持像 Maven 那样直接配置本地 artifact 仓库,但可以通过自定义 package 类型仓库把本地 ZIP 当作一个“假包”来安装。关键不是让 Composer 去扫描目录,而是显式声明这个 ZIP 对应的包名、版本和源信息。
常见错误是试图在 repositories 里写 "type": "artifact" 并指向一个 ZIP 文件路径——这会报错:Invalid repository type "artifact",因为 artifact 类型只在私有 Satis/Satis-like 服务中有效,且要求 ZIP 文件名严格匹配 vendor/name-version.zip 格式,本地文件系统无法自动解析。
- 必须使用
"type": "package" -
"dist"字段需完整指定"url"(支持file://协议或相对路径)、"type"(固定为zip)、"reference"(可空,但建议填个哈希或时间戳用于缓存失效) -
"autoload"和其他元信息必须手动补全,Composer 不会从 ZIP 中读取composer.json
{
"repositories": [
{
"type": "package",
"package": {
"name": "myorg/my-legacy-lib",
"version": "1.2.3",
"dist": {
"url": "./packages/my-legacy-lib-1.2.3.zip",
"type": "zip",
"reference": "20240520"
},
"autoload": {
"psr-4": {
"MyLegacy\\": "src/"
}
}
}
}
],
"require": {
"myorg/my-legacy-lib": "^1.2.3"
}
}
用 file:// URL 引用 ZIP 时路径必须绝对或正确解析
如果 ZIP 不在项目根目录下,用相对路径(如 "./packages/xxx.zip")通常可行,但某些 Composer 版本或运行环境(如 Windows + Git Bash)可能解析失败,表现为 Could not fetch https://api.github.com/... (404) 或静默跳过下载。
更稳妥的方式是用 file:// 绝对路径,尤其在 CI 或多用户环境中:
- Linux/macOS:用
"url": "file:///home/user/project/packages/mylib-1.2.3.zip" - Windows:用
"url": "file:///C:/project/packages/mylib-1.2.3.zip"(注意三个斜杠,盘符大写) - 避免空格和中文路径,否则可能触发 cURL 错误或 ZIP 解压失败
ZIP 包结构必须符合 Composer 安装预期
Composer 解压 ZIP 后,会把内容当作包的根目录。如果 ZIP 打包时多了一层文件夹(比如压缩了整个 my-legacy-lib-1.2.3/ 目录),那么 autoload 里的 "src/" 就会找不到——实际路径变成 my-legacy-lib-1.2.3/src/。
解决方法只有两个:
- 打包 ZIP 时,选中
src/、composer.json等文件,**不要包含外层目录**(即解压后直接看到src/,而不是my-legacy-lib-1.2.3/src/) - 或者在
"autoload"中调整路径,例如写成"MyLegacy\\": "my-legacy-lib-1.2.3/src/",但这会让版本号硬编码进 autoload,不可维护
验证方式:手动解压 ZIP,确认结构是否扁平。
安装后不会自动更新,且 composer update 可能忽略本地变更
一旦 ZIP 被成功安装,Composer 会把它缓存到 vendor/,后续 composer install 不再读取原始 ZIP。如果你修改了 ZIP 文件内容,必须强制刷新:
- 删掉
vendor/myorg/my-legacy-lib和composer.lock中对应条目 - 运行
composer update myorg/my-legacy-lib --with-dependencies - 或者加
--no-cache参数绕过本地缓存(但不推荐用于 CI)
没有钩子能监听 ZIP 文件变动,所以这种模式只适合稳定快照,不适合开发态热更新。
真正需要频繁迭代的本地包,应该用 "path" 仓库类型指向本地 Git 仓库或文件夹,而不是 ZIP。










