
本文详解如何使用 php 动态解析含地理坐标字符串的原始 json 数据,并正确构建符合规范的嵌套 json 结构(如 {"routes": [{...}, {...}]}),避免覆盖问题,确保每个路由对象独立添加。
在 PHP 中动态生成符合特定结构的 JSON 数据(尤其是含数组嵌套的对象)时,一个常见误区是反复赋值同一对象属性(如 $json->route_ID = ...),导致前序数据被后序循环覆盖——这正是原代码仅输出 "route_ID": "50" 的根本原因。
关键在于:Routes 必须是一个数组,且每次循环应向该数组追加一个全新的路由对象,而非复用并重写同一个对象实例。
以下是修正后的完整实现逻辑(已优化健壮性与可读性):
<?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);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new RuntimeException('Invalid input JSON string');
}
// 2. 初始化最终结构:Routes 作为空数组
$result = new stdClass();
$result->Routes = []; // ✅ 核心修正:声明为数组
// 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);
$geomPoints = [];
foreach ($coords as $coord) {
$parts = array_map('trim', explode(',', $coord));
if (count($parts) >= 2) {
// 注意:GeoJSON 和地图 API 通常为 [lng, lat],此处按需求转为 {lat, lng}
$geomPoints[] = [
'lat' => $parts[1],
'lng' => $parts[0]
];
}
}
// 4. 构建单个路由对象(全新 stdClass 实例)
$route = new stdClass();
$route->route_ID = $record['route_ID'] ?? '';
$route->geom = $geomPoints;
// 5. ✅ 追加到 Routes 数组(非赋值!)
$result->Routes[] = $route;
}
// 6. 输出标准化 JSON(带缩进便于调试)
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
?>输出示例:
立即学习“PHP免费学习笔记(深入)”;
{
"Routes": [
{
"route_ID": "49",
"geom": [
{
"lat": "-30.63607",
"lng": "147.499935"
}
]
},
{
"route_ID": "50",
"geom": [
{
"lat": "-30.63607",
"lng": "147.499935"
}
]
}
]
}注意事项:
- 始终使用 [] 向数组追加元素($array[] = $item),而非重复赋值同名属性;
- 使用 preg_replace 替代多次 str_replace,提升坐标清洗鲁棒性;
- 添加 json_last_error() 检查,避免静默失败;
- 若输入坐标含多点(如 "147.1, -30.1 147.2, -30.2"),preg_split('/\s+/', ...) 可可靠分割;
- 如需兼容更复杂 KML/GPX 输入,建议引入专用 XML 解析器(如 SimpleXML),而非正则硬解析。
通过结构化初始化 + 循环追加模式,即可稳定生成任意数量的嵌套 JSON 对象,完美适配地图 API、前端组件等消费场景。











