composer validate 仅校验 composer.json 的语法和 Composer 字段语义,不检查项目中其他 JSON 文件(如 config.json)的嵌套结构、语法错误或业务逻辑;验证嵌套 JSON 应用 php -r 调用 json_decode,或用 JSON Schema(如 opis/json-schema)校验结构合法性,辅以 TreeWalker 进行 diff 和遍历。

composer validate 对嵌套 JSON 数据完全无效
它只校验 composer.json 文件本身的 JSON 语法和 Composer 特定字段语义,对项目里任意其他 JSON 文件(比如 config.json、schema.json、data.json)一概不读——连文件名都不会扫一眼。
常见误操作是:把一个含深层嵌套结构的配置文件命名为 config.json,然后跑 composer validate 发现没报错,就以为“格式没问题”,结果运行时 json_decode() 直接返回 null。问题出在 JSON 本身,不是 Composer 配置。
- 嵌套过深、循环引用、超长字符串溢出等运行时问题,
composer validate压根不检查 - 字段值是否符合业务逻辑(如
"max_retries": -1或"timeout": "30s")也不在它的职责范围内 - 真正要验证嵌套数据,得用别的工具或自己写逻辑
用 php -r 直接解析是最准的语法校验方式
PHP 自带的 json_decode() 是最贴近运行环境的检验器。它会暴露所有 JSON 解析器真实遇到的问题,包括那些编辑器看不见的隐藏字符。
执行这行命令:
php -r "$j = file_get_contents('config.json'); $d = json_decode($j); if (!$d) { echo 'JSON error: ' . json_last_error_msg() . \"\n\"; }"
错误信息里写的 line 12 at column 5 就是真实出错位置,不是示意。盯三类高频问题:
- 中文引号或全角符号:如
'name': 'myapp'❌ → 必须是"name": "myapp" - 末尾逗号:嵌套对象或数组最后一项后多了一个
,,JSON 不允许 - BOM 头或零宽空格:用
xxd config.json | head或cat -A config.json | head -n 15查看不可见字符
嵌套结构合法性要用 JSON Schema 验证
语法正确 ≠ 结构合法。比如一个嵌套 5 层的 rules 数组,每项都该有 condition 和 action 字段,但 JSON 语法允许你漏掉其中任何一个——这时就得靠 JSON Schema。
安装验证器:
使用约定式提交(Conventional Commits)生成标准化的 Git 提交信息。适用于以下场景: (1) 暂存更改时需要提交信息; (2) 审查 diff 时希望获得结构化摘要; (3) 编写 PR 描述或变更日志(changelog)条目; (4) 用户明确要求“为本次更改编写提交信息”。 该功能会分析已暂存/未暂存的 diff,并生成按类型(type)划分范围的提交信息。
composer require justinrainbow/json-schema
示例校验逻辑:
<?php
$data = json_decode(file_get_contents('data.json'));
$schema = json_decode(file_get_contents('schema.json'));
$validator = new JsonSchema\Validator;
$validator->validate($data, $schema);
if (!$validator->isValid()) {
foreach ($validator->getErrors() as $error) {
echo sprintf("[%s] %s\n", $error['property'], $error['message']);
}
}
注意:justinrainbow/json-schema 已停止维护,新项目建议换用 opis/json-schema,但后者错误提示更晦涩,可搭配 m1x0n/opis-json-schema-error-presenter 提升可读性。
嵌套数据 diff 和遍历别手写递归
需要对比两个嵌套 JSON 是否一致?或者想批量修改某一层级的所有 "status" 字段?硬写 foreach + is_array() + 深度计数极易出错,且难以覆盖边界情况(如对象与数组混嵌、null 键、数字键转字符串)。
推荐用 lukascivil/treewalker:
composer require lukascivil/treewalker
它支持路径式访问、深度优先/广度优先遍历、结构差异比对(getdiff()),且自动处理数组/对象混合结构。例如:
$walker = new TreeWalker(['returntype' => 'array']); $diff = $walker->getdiff($old_config, $new_config); // 返回新增/删除/变更的完整路径列表
关键点:它不依赖 JSON 字符串,而是直接操作 PHP 原生数组/对象,所以不会因编码、BOM、浮点精度等问题引入额外干扰——这才是处理复杂嵌套数据该有的起点。

















