composer validate --strict --no-check-publish 是发布前必须执行的校验命令,它启用完整 schema 校验,可拦截字段拼写错误(如 requrie)、非法值(如 "license": "mit license")、格式违规(如 name 缺 vendor 前缀)等 90% 的 packagist 拒绝原因,而默认模式仅基础检查,极易漏报。

Composer 发布包被拒,90% 不是 Packagist 拒绝你,而是 composer validate --strict --no-check-publish 在本地就该拦下你——它不报错,Packagist 才真会拒。
composer validate 报错但没给行号?先用 php -r json_decode 定位
默认 composer validate 只报 JSON decoding failed,不显示具体位置。这不是它偷懒,而是底层调用的 json_decode() 默认不返回列号。别靠猜,直接甩命令:
-
php -r "$j = file_get_contents('composer.json'); $d = json_decode($j); if (!$d) { echo json_last_error_msg()."\n"; }"—— 输出类似Syntax error on line 12, column 5,精准到字符 - 若提示
Control character error或Unexpected token,立刻查 BOM(xxd composer.json | head看是否含ef bb bf)或零宽空格(编辑器开「显示不可见字符」) - 别信 IDE 的“自动修复”:它可能把
// comment美化成合法 JSON,但 JSON 标准根本不支持注释
加 --strict 才算真正校验字段合法性
--strict 不是“更严一点”,是启用完整 JSON Schema + 语义检查。默认模式下很多低级错误会被放过:
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
- 拼错字段名:
"requrie"(少个 i)默认不报;加--strict直接失败 -
"license": "MIT License"默认只警告;--strict视为错误(必须是 SPDX 标识符,如"mit") -
"name": "myapp"缺 vendor 前缀,默认不拦;--strict拒绝(必须是"vendor/name"格式) -
"autoload": {"psr-4": {"App": "src/"}}少了命名空间末尾反斜杠,--strict会报错(应为"App\")
CI/CD 中必须固定用 --strict --no-check-publish --no-check-lock
发布前校验不是走形式,是卡点。CI 里用裸 composer validate 等于没校验:
-
--no-check-publish:跳过 Packagist 发布策略检查(比如 license 是否在白名单),避免 CI 因网络或策略中断 -
--no-check-lock:明确告诉它只盯composer.json,不比对composer.lock(那个该由composer install --dry-run覆盖) - 老版本 Composer(如 1.x)容忍度高,新版本(2.5+)对
"type"默认值、URL 协议(必须https://)、"config.platform"字段校验更严——CI 镜像必须锁定 Composer 版本
validate 通过 ≠ install 成功,但 validate 失败一定发不了包
composer validate 是纯静态检查:不联网、不解析版本约束、不验证 autoload 路径是否存在、不读 composer.lock。所以:
- 写
"require": {"monolog/monolog": "^3.0.0-dev"},validate认为合法,install却因 dev 分支不可解析失败 -
"repositories"里漏了url字段?validate直接报错(schema 强制要求),Packagist 也绝对拒收 - 真正卡住发布的,往往不是少逗号,而是
psr-4映射末尾反斜杠缺失、name含下划线或大写字母、autoload路径用了双斜杠"src//"—— 这些只有--strict会揪出来










