新项目声明离线ZIP包仓库必须在composer.json根级repositories中显式配置type为"artifact"、url指向ZIP目录(如"./offline-zips"),且ZIP命名、内部composer.json的name/version、require声明三者字面完全一致,否则静默跳过;还需禁用packagist并清缓存。

新项目怎么声明离线 ZIP 包仓库
必须在新项目的 composer.json 里显式配置 repositories,且类型为 artifact,不能只靠拷贝 vendor 或改 require。否则 Composer 仍会尝试连 Packagist,报 Could not find package。
关键点:
-
type必须是"artifact",不是"package"或"path" -
url必须指向包含 ZIP 文件的**目录路径**(不是单个 ZIP),且该路径下所有 ZIP 必须符合命名规范:vendor-name/package-name/version-hash/package-name-version-hash.zip - 该
repositories条目要写在根级,例如:[{"type": "artifact", "url": "./offline-zips"}] - 路径用相对路径(如
"./offline-zips"),绝对路径(/opt/zips)在某些环境会静默失败
ZIP 包目录结构不对会导致 install 静默跳过
Composer 只认特定结构的 ZIP 目录:它会扫描 url 指向目录下的所有 .zip 文件,并按文件名解析包名和版本。名字错一个字符、多一层嵌套、或 ZIP 内无合法 composer.json,都会被忽略——不报错,也不装。
正确结构示例(Linux/macOS 路径):
./offline-zips/
└── monolog/monolog/
└── 2.10.0.0/
└── monolog-monolog-6a8c4b5.zip
常见错误:
- ZIP 放在
./offline-zips/monolog-monolog-2.10.0.zip(扁平一层)→ 不识别 - ZIP 名含大写字母或下划线(如
Monolog_Monolog-2.10.0.zip)→ 解析失败 - ZIP 解压后根目录没有
composer.json,或其中name字段与 ZIP 路径不匹配 - 目录权限不足,PHP 进程无法
scandir()→ 静默 fallback 到网络
为什么 composer install 还是去联网
即使 repositories 配对了、ZIP 目录也对,composer install 仍可能触发网络请求。根本原因不是缓存没清,而是默认行为未切断:
- 没设
COMPOSER_DISABLE_NETWORK=1环境变量 → 所有--no-xxx参数都无效 - 全局还残留
repo.packagist配置 → 运行composer config --global repo.packagist false彻底禁用 -
composer.lock里存在"source": {"type": "git", ...}条目 → 离线时无法校验,install 必败;需提前用在线机重生成 lock(仅含 dist) - 项目
composer.json里写了"repositories": [{"type": "packagist", "url": false}]→ 在COMPOSER_DISABLE_NETWORK=1下直接退出,不是忽略
装上了但 Class not found 怎么办
这通常和 ZIP 包本身无关,而是自动加载没生效。artifact 仓库不会自动触发 autoload 更新,尤其当 ZIP 包里 composer.json 的 autoload 字段和源包不一致时。
必须手动刷新:
- 进新项目根目录,运行
composer dump-autoload -o - 确认 ZIP 包内
composer.json的autoload正确(如"psr-4": {"Monolog\": "src/"}) - 如果包含服务提供者(如 Laravel/ThinkPHP 扩展),仍需手动注册到框架配置中 —— Composer 不管这部分
- 别依赖 vendor/autoload.php 自动加载旧路径;改了 ZIP 结构后,旧映射还在 cache 里,
-o强制重建才可靠
最易被忽略的是 ZIP 文件名和内部 composer.json 的 name + version 必须三方完全一致:文件路径解析出的名字、ZIP 内 JSON 声明的名字、你在 require 里写的字符串,三者逐字相同,缺一不可。











