composer validate 仅校验 scripts 字段的 json 结构和 schema 合规性,不解析、不执行、不检查命令是否存在或参数是否合法,也无法识别事件名拼写错误或 shell 片段逻辑问题。

Composer validate 会检查 script 字段的 JSON 语法,但不校验脚本内容本身
composer validate 默认只做基础 JSON 结构校验和 Composer schema 合规性检查。它会确认 scripts 是一个合法对象、每个键是字符串、值是字符串或字符串数组——但不会解析或执行任何脚本内容,也不关心命令是否存在、参数是否合法、是否拼写错误。
比如以下写法能通过 composer validate,但实际运行会失败:
"scripts": {
"test": ["phpunit --invalid-flag"]
}
-
composer validate不调用 shell,不查phpunit是否在 PATH 中 - 不验证
--invalid-flag是否被 phpunit 支持 - 不识别数组中混入布尔值或 null 的非法类型(如
"test": [true]会被 schema 拒绝,但"test": "php -l"即使命令不存在也照过)
想让 script 语法更健壮?得靠 schema + 自定义约束
Composer 自身的 JSON Schema(https://getcomposer.org/schema.json)对 scripts 的定义很宽松:仅要求值为 string 或 array,且数组元素必须是 string。这意味着你无法靠 composer validate 拦住常见错误,比如:
- 误写成
"post-install-cmd": "echo hello"(正确事件名是post-install-cmd,但拼成post-intall-cmd也能过校验) - 脚本命令里漏了引号导致 JSON 解析失败(如
"test": "php -l src/*.php"在 Windows 下可能因*被 shell 展开而崩,但 validate 不管) - 使用了 Composer 2.2+ 新增的
script-event类型钩子(如pre-package-install),旧版 Composer 运行时报错,validate 却不报
真正起作用的是:composer validate --strict —— 它会启用额外的 schema 级别检查(比如禁止未知的顶级字段),但依然不碰 scripts 内容逻辑。
替代方案:用 composer.json 的 $ref 或自定义 schema 做深度校验
如果团队需要强制规范 script 写法(比如统一要求所有命令加 -d memory_limit=-1,或禁止裸 php 调用),就得绕开 composer validate,改用外部工具:
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
- 用
jq提取并检查scripts键是否存在、是否为 object、是否有非法 key(如含空格或控制字符) - 写 PHP 脚本加载
json_decode(file_get_contents('composer.json'), true),遍历scripts值,用preg_match('/^\w+.*$/', $cmd)初筛命令格式 - 集成到 CI:在
composer validate后追加composer run-script --dry-run test(注意:--dry-run 仅模拟,不执行,但会触发 event 解析和命令拼接逻辑,比 validate 更早暴露问题)
不过要注意:--dry-run 依赖当前环境已安装对应二进制(如 phpunit),且不能检测变量替换错误(如 "test": "php ${TEST_FILE}" 中 ${TEST_FILE} 未定义)。
script 字段里写复杂逻辑?先考虑拆到独立脚本文件
当 scripts 开始出现多行、条件判断、错误处理时,composer validate 就彻底失去意义了。比如:
"scripts": {
"build": "if [ -f .env ]; then php build.php; else echo 'missing .env'; exit 1; fi"
}
这种 shell 片段既难维护,又无法被 validate 覆盖。更可靠的做法是:
- 把逻辑移到
bin/build或scripts/build.php - 在
composer.json中只留干净调用:"build": "php scripts/build.php" - 这样
composer validate仍可保证 JSON 正确,而真实逻辑由 PHP 自身语法检查、IDE 提示、单元测试兜底
真正容易被忽略的不是语法对错,而是 script 执行上下文的不确定性:当前工作目录、环境变量继承、PHP SAPI 差异(cli vs cgi)、以及 Composer 自己对 $argv 的截断处理——这些全不在 validate 的职责范围内。










