
本文详解如何正确解析并遍历多层嵌套的 JSON 数据,通过 json_decode() 构建对象树,使用嵌套 foreach 定位目标子项,并安全提取关联字段(如与 "Id": 2054 同级的 "Class" 值),避免字符串匹配导致的误判与结构失真。
本文详解如何正确解析并遍历多层嵌套的 json 数据,通过 json_decode() 构建对象树,使用嵌套 foreach 定位目标子项,并安全提取关联字段(如与 "id": 2054 同级的 "class" 值,避免字符串匹配导致的误判与结构失真。
在处理真实项目中的 JSON 数据(如赛车游戏配置文件 r3e-data.json)时,常见误区是将整个 JSON 当作纯文本逐行扫描——这不仅效率低下,更易因字段名重复、数值嵌套或格式缩进引发误匹配(例如搜索 "2054" 可能误中 "Id": 20541 或注释内容)。正确做法是将其完整解析为 PHP 对象或数组,再基于语义结构进行导航式查找。
该 JSON 文件采用典型的两层嵌套结构:根对象包含 cars 键,其值为以车型 ID 为键的关联对象;每个车型对象又包含 liveries 键,其值为肝色(涂装)数组,而每个涂装对象才真正包含 Id 和 Class 字段。因此,必须按层级深入访问:
<?php
$search = '2054';
$url = 'https://www.php.cn/link/e18d4612b5341e4a20de3c095a552597';
// ✅ 正确:一次性读取完整 JSON 字符串
$jsonString = file_get_contents($url);
if ($jsonString === false) {
die('Failed to fetch JSON data.');
}
// ✅ 正确:直接解码为对象(保持原始键名,便于链式访问)
$jsonData = json_decode($jsonString);
if (json_last_error() !== JSON_ERROR_NONE) {
die('Invalid JSON format: ' . json_last_error_msg());
}
$found = false;
// ✅ 按结构遍历:先遍历 cars,再遍历每辆车的 liveries
foreach ($jsonData->cars as $carId => $carData) {
if (!isset($carData->liveries) || !is_array($carData->liveries)) {
continue;
}
foreach ($carData->liveries as $livery) {
// ⚠️ 注意:JSON 中 Id 是整数,但搜索值可能为字符串,建议统一类型比较
if ((string)$livery->Id === $search) {
$found = true;
echo "Found livery:\n";
echo " Id: " . $livery->Id . "\n";
echo " Class: " . $livery->Class . "\n";
// 可选:同时输出所属车型便于调试
echo " Car: " . $carId . "\n";
break 2; // 找到即退出双层循环
}
}
}
if (!$found) {
echo "No livery with Id = {$search} found.\n";
}
?>关键要点与最佳实践:
- 避免 file() + json_encode(json_decode()) 的冗余操作:file() 返回字符串数组(每行一项),破坏 JSON 结构完整性;而 json_encode(json_decode()) 属无意义往返转换,徒增开销且可能改变数据类型(如整数变字符串)。
- 优先使用对象访问语法(->):比数组语法(['key'])更直观体现 JSON 原始结构,且无需额外 json_decode($json, true) 切换模式。
- 务必校验解码结果与网络请求状态:file_get_contents() 失败返回 false;json_decode() 失败返回 null,需用 json_last_error() 显式检查。
- 类型安全比较:$livery->Id 是整数,$search 是字符串,强制 (string) 转换确保精确匹配,防止 2054 == "2054" 在松散比较下虽成立,但逻辑上应追求显式一致。
- 提前终止循环:使用 break 2 立即跳出嵌套 foreach,提升性能,尤其当数据量较大时。
掌握这种“结构驱动”的 JSON 查询方式,不仅能准确获取目标字段,更能为后续扩展(如批量查询、条件过滤、字段映射)奠定坚实基础。










