私有包name字段必须为全小写、连字符分隔的vendor/package格式,严格匹配git仓库所有权,且psr-4命名空间须与name小写形式逐字映射(如acme/internal-api→acmeinternal-api),版本仅识别带v前缀的git tag。

私有包 name 字段必须全小写 + 连字符,且 vendor/package 严格匹配 Git 仓库所有权
你的 name 字段不是“起个名字”那么简单——它直接决定 Packagist(或私有镜像)能否识别、Composer 能否解析依赖、PSR-4 自动加载器能否找到类。错误命名会导致 Could not find package 或 Class not found,但报错位置往往远离问题根源。
关键约束有三条:
-
vendor和package都必须全小写,中间只用一个/分隔,例如acme/internal-api,不能是Acme/InternalApi或acme_internal-api -
vendor名需与你在私有 Git 服务器(如 GitLab/GitHub Enterprise)上的组织/用户名完全一致;若仓库 URL 是https://git.internal/acme/internal-api.git,那name就只能是acme/internal-api - 禁止使用保留词(
php、composer、ext)、纯数字、开头/结尾的连字符或点,例如123/api、-mylib、mylib-均非法
PSR-4 命名空间必须与 name 字段小写形式逐字映射,不可驼峰、不可下划线
很多团队在 composer.json 里写 "psr-4": {"Acme\InternalApi\": "src/"},结果类加载失败——因为 Composer 不会把 acme/internal-api 自动转成 AcmeInternalApi;它只做字面映射,且文件系统(尤其 Linux)区分大小写。
正确做法只有一条:把 name 中的 / 替换为 ,连字符 - 保留原样,全部小写:
-
name:acme/internal-api→ 命名空间应为acmeinternal-api -
name:mycompany/logger-component→ 命名空间应为mycompanylogger-component - 对应 PSR-4 配置:
"psr-4": {"acme\internal-api\": "src/"}
别试图“美化”命名空间。PHP 自动加载器不解析驼峰或下划线,MyCompanyLogger 这种写法在 psr-4 下永远找不到文件。
私有仓库 URL 和 repositories 配置中的 type 必须与实际服务类型一致
你填了 "type": "vcs",但指向的是 Artifactory 的 Composer 仓库地址?或者填了 "type": "composer",却给了一个 Git HTTPS 地址?这类错配不会立刻报错,而是在 composer update 时静默跳过,最终提示 Could not find package。
对照表帮你快速判断:
- 指向 Git/SVN/Hg 仓库地址(如
https://git.internal/acme/internal-api.git)→"type": "vcs" - 指向 Satis 或 Artifactory 的 Composer 协议接口(如
https://packages.internal/)→"type": "composer",且 URL 末尾必须带/ - 指向本地
.tar.gz包目录(如/opt/artifacts/)→"type": "artifact" - 指向同机目录源码(如
./packages/internal-api)→"type": "path",且 require 时必须加@dev
Artifactory 上还容易漏掉一点:Virtual 仓库的 “Enable Default Deployment Repository” 必须勾选,否则 composer publish 会拒绝上传。
版本号必须绑定 Git tag,且 tag 名强制带 v 前缀
私有包的 ^1.2.0 依赖不会匹配 git checkout main 的最新代码,也不会认 git tag 1.2.0(缺 v)。Composer 只从 Git tag 解析版本,且只信任形如 v1.2.0、v2.0.0-beta.1 的标签。
实操要点:
- 打 tag 必须用
git tag v1.2.0,然后git push --tags -
composer.json中的version字段完全被忽略,删掉它,避免干扰 - Satis 构建时若看到
Could not parse version constraint dev-main,说明目标仓库的composer.json里写了"version": "dev-main",这是非法值,必须删除 - CI 流水线应在 tag 推送后自动触发构建,确保每个 tag 对应一次完整验证(测试 + 静态分析 + 兼容性检查)
最常被忽略的一点:私有包的 name 和命名空间一旦发布,就很难安全修改。大小写、连字符、vendor 名变更都会导致下游项目 composer update 失败或类加载断裂。设计阶段定下来,比后期补救成本低得多。











