Artifact仓库必须使用绝对路径或规范相对路径,仅支持目录路径(如"./packages"),目录下需平铺存放vendor/package-version.zip格式的ZIP包,且ZIP内composer.json须在根目录、name和version须与文件名逐字一致,同时需禁用packagist.org。

Artifact仓库必须用绝对路径或规范相对路径
Composer 的 artifact 类型仓库不支持 file:// 协议,也不接受 ZIP 文件路径;它只认一个**目录路径**,且该目录下平铺存放所有 ZIP 包。写成 "url": "./packages/mylib-1.2.0.zip" 或 "url": "file:///path/to/pkg.zip" 会直接报错 Invalid repository type "artifact"。
正确做法是把所有 ZIP 放进一个干净目录(如 ./packages),然后配置:
{
"repositories": [
{
"type": "artifact",
"url": "./packages"
}
]
}
注意三点:
-
url值结尾不能加斜杠("./packages/"在某些 Composer 版本下会被静默忽略) - 推荐用绝对路径(如
/opt/myproject/artifacts),避免 CI 或多用户执行时因工作目录不同导致路径失效 - 该目录必须真实存在,且 PHP 进程(如 www-data 或 php-fpm 用户)有读取权限
ZIP包命名和内部结构必须字面一致
Artifact 仓库不解析 ZIP 内容,而是靠文件名反向推导包信息。一旦不一致,就静默跳过——不是报错,是根本找不到包。
文件名格式必须为: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 和 version 字段,必须与 ZIP 文件名中出现的字符串**逐字完全一致**:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 文件名是
acme/utils-1.2.0.zip→composer.json里必须是"name": "acme/utils"、"version": "1.2.0" -
version必须是语义化版本,不支持dev-main、dev-develop等别名 - 大小写敏感,
Acme/Utils和acme/utils被视为不同包
require之后必须运行 update 才能识别新ZIP
composer install 完全不扫描 repositories,它只按 composer.lock 安装。哪怕你刚把 ZIP 放进 ./packages,再跑 install 也毫无反应。
要让新 ZIP 生效,必须触发版本解析:
- 首次引入:运行
composer require acme/utils:1.2.0(版本号必须精确匹配) - 已有依赖更新:运行
composer update acme/utils或composer update - 删掉
vendor/和composer.lock后再composer install --no-cache也行,但前提是packagist.org已禁用(见下一条)
离线环境必须显式禁用 packagist.org
只加 artifact 仓库,不关默认源,Composer 仍会 fallback 查询 packagist.org,导致看似“没连外网”实则请求超时失败,或私有包被忽略。
必须在 composer.json 顶层加:
"packagist.org": false
完整配置示例:
{
"repositories": [
{
"type": "artifact",
"url": "/opt/myproject/artifacts"
}
],
"packagist.org": false,
"require": {
"acme/utils": "1.2.0"
}
}
漏掉这行,composer install 或 update 都可能卡住、报 Could not find package,而 ZIP 其实就在目录里——这是离线部署最常踩的坑。
真正难的不是打包,是三处字面一致性:ZIP 文件名、内部 composer.json 的 name/version、require 里的声明,缺一不可,错一个字符就静默失效。

















