
本文详解如何使用 php 动态构建符合特定嵌套格式的 json 数据,重点解决多条路由(routes)及其地理坐标(geom)数组的程序化生成问题,并修正原始代码中因对象重复赋值导致仅保留最后一项的典型错误。
在 PHP 中构建结构化 JSON 数据时,一个常见误区是将新对象反复赋值给同一变量(如 $json->route_ID = ...),这会导致前序数据被覆盖——正如原代码中最终只输出 route_ID: "50" 所示。正确做法是将每条路由作为独立元素追加到数组中,再整体封装为 Routes 键下的 JSON 数组。
以下是优化后的完整实现:
147.499935,-30.63607 "},{"route_ID":"50","geom":""}]'; // 1. 解析原始 JSON 字符串为关联数组 $jsonArray = json_decode($jsonString, true); // 2. 初始化顶层容器对象 $json_Routes = new stdClass(); $json_Routes->Routes = []; // ✅ 关键:初始化为数组,而非对象或 null // 3. 遍历每条路由记录,逐个构建并追加 foreach ($jsonArray as $record) { // 解析 geom 中的坐标字符串(支持空格/换行分隔的多组坐标) $geomString = $record["geom"]; $geomString = preg_replace('/ 147.499935,-30.63607 |<\/coordinates><\/LineString>/i', '', $geomString); $geomString = trim($geomString); // 拆分坐标对(兼容含空格、制表符、换行的格式) $coords = preg_split('/\s+/', $geomString, -1, PREG_SPLIT_NO_EMPTY); $route_geom = []; foreach ($coords as $coord) { if (strpos($coord, ',') !== false) { [$lng, $lat] = array_map('trim', explode(',', $coord)); $route_geom[] = [ 'lat' => $lat, 'lng' => $lng ]; } } // 构建单条路由对象(使用关联数组更直观,后续 json_encode 自动转为对象) $route = [ 'route_ID' => $record['route_ID'], 'geom' => $route_geom ]; // ✅ 追加到 Routes 数组(非覆盖赋值) $json_Routes->Routes[] = $route; } // 4. 输出标准化 JSON(带缩进便于调试) echo json_encode($json_Routes, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); ?>
关键改进点说明:
- $json_Routes->Routes = []:显式初始化为空数组,确保后续 [] 操作可安全追加;
- 避免重复赋值对象属性:不再用 $json->route_ID = ... 覆盖同一变量,而是每次新建 $route 数组;
- 健壮的坐标解析:使用 preg_split('/\s+/', ...) 替代 explode(' '),兼容多空格、换行等不规则分隔;
- 类型安全处理:array_map('trim', ...) 清除坐标前后空格,防止解析异常;
- 输出优化:JSON_PRETTY_PRINT 提升可读性,JSON_UNESCAPED_UNICODE 避免中文乱码(如有)。
注意事项:
立即学习“PHP免费学习笔记(深入)”;
- 原始 $jsonString 中 geom 的坐标格式为 lng,lat(经度在前),而目标 JSON 要求 "lat" 和 "lng" 字段,因此赋值时需严格按 $var[1](纬度)、$var[0](经度)顺序映射;
- 若实际数据中存在无效坐标(如缺失逗号、非数字字符),建议增加 is_numeric() 校验与异常处理;
- 如需更高性能或处理海量数据,可考虑使用 json_decode($jsonString) 返回对象后直接遍历,避免 true 参数带来的数组开销。
通过以上重构,即可稳定生成符合要求的嵌套 JSON 结构,且具备良好的可维护性与扩展性。











