
本文详解如何使用 php 动态构建符合特定嵌套格式的 json 数据,重点解决多条路由(routes)及其地理坐标(geom)数组的程序化生成问题,并修正原始代码中因对象重复赋值导致仅保留最后一项的典型错误。
在 PHP 中构建结构化 JSON 数据时,一个常见误区是将新对象反复赋值给同一变量(如 $json->route_ID = ...),这会导致前序数据被覆盖——正如原代码中最终只输出 route_ID: "50" 所示。正确做法是将每条路由作为独立元素追加到数组中,再整体封装为 Routes 键下的 JSON 数组。
以下是优化后的完整实现:
<?php
$jsonString = '[{"route_ID":"49","geom":"<LineString><coordinates>147.499935,-30.63607 </coordinates></LineString>"},{"route_ID":"50","geom":"<LineString><coordinates>147.499935,-30.63607</coordinates></LineString>"}]';
// 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('/<LineString><coordinates>|<\/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 结构,且具备良好的可维护性与扩展性。











