
本文详解如何使用 php 动态解析含地理坐标字符串的原始 json 数据,并将其转换为符合嵌套数组规范的标准化 json 格式,重点解决多路由对象的正确追加与结构组装问题。
在 PHP 中构建符合特定结构的 JSON 数据时,常见误区是反复覆写同一对象属性(如 $json->route_ID),导致最终仅保留最后一次循环的结果。要生成类似 {"Routes": [{...}, {...}]} 的多元素 JSON,关键在于:将 Routes 显式声明为数组,并在每次循环中向其追加一个独立的对象(而非覆盖)。
以下是修正后的完整实现逻辑:
$jsonString = '[{"route_ID":"49","geom":"147.499935,-30.63607 "},{"route_ID":"50","geom":"147.499935,-30.63607 "}]';
$jsonArray = json_decode($jsonString, true);
$json_Routes = new stdClass();
$json_Routes->Routes = []; // ✅ 关键:初始化为数组,支持多次 push
foreach ($jsonArray as $record) {
// 解析 geom 字段中的坐标字符串
$geomString = $record["geom"];
$geomString = preg_replace('/|<\/coordinates><\/LineString>/i', '', $geomString);
$geomString = trim($geomString);
$coords = array_filter(array_map('trim', explode(' ', $geomString)));
$route_geom = [];
foreach ($coords as $coord) {
if (strpos($coord, ',') !== false) {
[$lng, $lat] = array_map('trim', explode(',', $coord));
$route_geom[] = ['lat' => $lat, 'lng' => $lng]; // 注意:GeoJSON 习惯是 [lng, lat],此处按需求保留 lat/lng 键名
}
}
// 构建单个 route 对象(使用关联数组更直观,也可转为 stdClass)
$route = [
'route_ID' => $record['route_ID'],
'geom' => $route_geom
];
// ✅ 正确追加到 Routes 数组中
$json_Routes->Routes[] = $route;
}
// 输出标准 JSON(自动处理嵌套与转义)
echo json_encode($json_Routes, JSON_PRETTY_PRINT); 输出示例:
{
"Routes": [
{
"route_ID": "49",
"geom": [
{
"lat": "-30.63607",
"lng": "147.499935"
}
]
},
{
"route_ID": "50",
"geom": [
{
"lat": "-30.63607",
"lng": "147.499935"
}
]
}
]
}注意事项:
立即学习“PHP免费学习笔记(深入)”;
- 避免混用 stdClass 与数组操作;推荐统一使用关联数组([])构建结构,最后由 json_encode() 自动转换,语义更清晰、容错性更强;
- 坐标解析建议使用正则替代多次 str_replace,提升健壮性(如处理空格、换行、多余分隔符);
- 若输入中存在多组坐标(如 "147.499935,-30.63607 147.499868,-30.63631"),explode(' ', ...) 需配合 array_filter() 清除空元素;
- 最终调用 json_encode() 时可添加 JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT 提升可读性与中文兼容性。
通过明确数据容器类型(数组)、合理组织循环内对象构造,并利用 PHP 的动态数组追加机制([]),即可稳定、可扩展地生成任意数量嵌套 JSON 元素。











