Composer包名必须为全小写、短横线分隔的两段式vendor/package格式,单段名会被补为root/xxx导致依赖失效,含大写字母、下划线、点号或双斜杠均非法。

Composer包名不是“起个好听的名字”,而是必须严格匹配其解析逻辑的标识符;写错一个字符,别人就 require 不到,autoload 会失效,Packagist 直接拒收。
vendor/package 格式为什么非得写两段?
单段名如 "name": "my-utils" 会被 Composer 自动补成 root/my-utils,而 root 并不存在——这不是“默认值”,是硬编码 fallback,会导致:
- 别人在自己的
composer.json中写"require": {"my-utils": "^1.0"},报错Could not find package my-utils - 即使手动写
"require": {"root/my-utils": "^1.0"},也极难维护,且 Packagist 不接受root/xxx形式的提交 - 本地用
path仓库测试时看似能装,但一发布就失败,错误信息里根本不会提示“你少写了 vendor”
小写 + 短横线(kebab-case)是硬性要求,不是风格建议
以下写法全部非法,composer install 或 composer validate 会直接中断:
-
"name": "MyVendor/my_package"→ 含大写字母和下划线,报错Invalid package name "MyVendor/my_package": Package names should be lowercase and use dashes for word separation -
"name": "myvendor/my.package"→ 点号在 package 段非法(仅 vendor 段允许用于域名反写,且需转义为中划线) -
"name": "myvendor//my-package"→ 双斜杠、空段、开头或结尾斜杠均被拒绝
正确示例只有一种模式:"name": "acme/http-client"、"name": "example-com/logger"。别依赖 GitHub 仓库名,它和包名完全解耦。
改名后 autoload 失效?问题不在 dump-autoload,而在映射没对齐
把 "name": "old/lib" 改成 "name": "new/lib" 后,常见错误是只改了 name 字段,却忘了三件事:
-
autoload里的 PSR-4 前缀仍写的是"Old\Lib\": "src/",应同步改为"New\Lib\": "src/"(命名空间本身可含大小写,但前缀必须与实际代码一致) - src/ 下的目录结构仍是
src/Old/Lib/,而 PSR-4 映射"New\Lib\": "src/"要求类文件在src/New/Lib/下,否则自动加载器找不到 - 没删
vendor/和composer.lock,Composer 会缓存旧 name,导致dump-autoload生成的vendor/composer/autoload_psr4.php里仍有旧映射
vendor 名选什么?别用系统用户名或随意造词
vendor 是你的全局身份,不是昵称。选错会导致协作混乱、Packagist 同步失败、甚至被误认为冒名:
- 优先用你在 Packagist 注册的用户名或组织名(如
symfony、laravel),保持一致 - 若用域名,必须反写并转义点号:
example.com→example-com,而非example.com或com.example - 禁用
php、ext、lib等保留字作 vendor,虽不报错,但 Packagist 审核大概率拒收 - 避免用
root、local、test这类无意义 vendor,它们无法建立可信标识
最常被忽略的一点:package 名里的短横线数量没有上限,但语义要清晰;acme/api-v2-client 比 acme/apiv2client 更易读,也更符合人类直觉——而 Composer 解析器根本不关心“是否易读”,它只校验字符集和格式。











