私有包找不到是因artifact仓库对ZIP文件名、内部composer.json、配置三者字面完全一致有硬性校验,错一个字符即静默跳过;URL须指向真实目录(如"./packages"),不可带斜杠,且必须配"packagist.org": false。

私有包始终找不到,不是路径写错了,而是 artifact 仓库对 ZIP 文件名、内部结构、配置位置三者都有硬性校验——错一个字符就静默跳过,不报错也不提示。
artifact仓库URL必须指向目录,且不能带末尾斜杠
Composer 会把 url 当作本地文件系统路径直接扫描,不是 HTTP 请求地址。常见错误是写成 "./packages/"(带斜杠)或 "./packages/mylib-1.0.0.zip"(指向文件)。
-
url值必须是真实存在的目录路径,如"./packages"或"/opt/artifacts" - 该目录下所有 ZIP 文件必须平铺放置,不能嵌套子目录
- PHP 进程需有读取权限(Linux 下注意
www-data或php-fpm用户能否访问) - Windows 用户用绝对路径时建议写成
"C:/artifacts",避免反斜杠转义问题
ZIP 文件名和内部 composer.json 必须字面完全一致
Composer 不解压 ZIP,只靠文件名反向推导包信息。它提取 vendor/package-version.zip 中的三段,再比对 ZIP 内 composer.json 的 name 和 version 字段。
- 文件名格式严格为:
vendor/package-version.zip(注意是斜杠,不是中划线) - 示例正确:
acme/utils-1.2.0.zip,错误:acme-utils-1.2.0.zip或acme/utils-v1.2.0.zip - 解压后
composer.json必须在 ZIP 根目录,不能是acme-utils-1.2.0/composer.json -
composer.json中"name": "acme/utils"和"version": "1.2.0"必须与文件名中出现的字符串**逐字相同**
项目级 composer.json 必须显式禁用 packagist.org
即使加了 artifact 源,只要没关掉默认源,Composer 就仍会 fallback 查询 packagist.org,你的 ZIP 包永远不被考虑。
- 在项目
composer.json顶层添加:"packagist.org": false - 不要写成
"packagist": false或"packagist.org": "false"(字符串) - 确认没有其他配置覆盖它:运行
composer config --list,检查repo.packagist输出为空 - 删掉
vendor/和composer.lock后再执行composer install --no-cache
require 时必须精确匹配版本号,且需先 update 才能识别新 ZIP
composer install 只按 composer.lock 安装,不会重新扫描 ZIP 目录;只有 update 或显式 require 才触发 artifact 元数据刷新。
- 新增 ZIP 后,必须运行
composer update acme/utils或composer update -
require命令要带精确版本:composer require acme/utils:1.2.0(不能写^1.2) - 如果 ZIP 是新生成的,但
composer update仍提示找不到,检查是否漏了"packagist.org": false或文件名大小写不一致 - 推荐用
composer archive --format=zip --dir=./packages/生成 ZIP,它自动处理命名和结构
最容易被忽略的是:artifact 仓库不支持任何动态行为,它就是个静态文件扫描器。一旦配置生效,Composer 就彻底离线;但一旦某处命名或路径出错,它也不会告诉你哪里错了,只会安静地跳过——所以验证必须靠 composer config --list 和 composer update -v 看实际加载路径。











