PHP JSON对象嵌套循环数据语法

PHP JSON对象嵌套循环数据语法,php,json,object,for-loop,Php,Json,Object,For Loop,我试图循环使用一些JSON数据并提取特定的值。下面是JSON数据和部分工作的代码 $jsondata = ' [ { "id" : "421356", "trip_update" : { "trip" : { "trip_id" : "421356", "start_time" : "12:05:00", "start_date" : "20130926", "route_id" : "15" }, "stop_

我试图循环使用一些JSON数据并提取特定的值。下面是JSON数据和部分工作的代码

$jsondata = '
[
  {
  "id" : "421356",
  "trip_update" : {
    "trip" : {
      "trip_id" : "421356",
      "start_time" : "12:05:00",
      "start_date" : "20130926",
      "route_id" : "15"
    },
    "stop_time_update" : {
       "stop_sequence" :70,
      "departure" : {
        "delay" : 240,
        "time" : 1380215057
      },
      "stop_id" : "6090"
    },
    "stop_time_update" : {
       "stop_sequence" :71,
      "departure" : {
        "delay" : 240,
        "time" : 1380215075
      },
      "stop_id" : "6095"
    }
  }
}]';
$result = json_decode($jsondata);

foreach($result as $value) {
  echo "trip_id: ".$value->trip_update->trip->trip_id;
  if (gettype($value->trip_update ) == "object") {
    foreach($value->trip_update as $item) {
       echo " - stop_sequence: ".$item->stop_sequence;
    }
  }
}
我可以在“trip\u update->trip”下获取第一级数据。但“行程更新”中也可以有任意数量的“停止时间更新”数据。因为这个数据与trip_update数据相关,所以我需要遍历它并将其关联起来

最终目标是将此数据保存到数据库中(代码中未显示),因此为了清晰起见,在本例中,这将是我希望保存的简化的2行DB数据:

trip_id,stop_sequence
421356,70
421356,71
源数据中可以有任意数量的stop_序列

以下是代码的交互式链接,供您编辑或处理:

您应该重新编写JSON-您有多个同名键,尝试执行
print\r($result)
查看我在说什么-PHP将一次又一次地覆盖“stop\u time\u update”键,您将只能访问最后一个条目。相反,您应该这样组织JSON:

[
  {
  "id" : "421356",
  "trip_update" : {
    "trip" : {
      "trip_id" : "421356",
      "start_time" : "12:05:00",
      "start_date" : "20130926",
      "route_id" : "15"
    },
    "stop_time_update" : [{
       "stop_sequence" :70,
      "departure" : {
        "delay" : 240,
        "time" : 1380215057
      },
      "stop_id" : "6090"
    }, {
       "stop_sequence" :71,
      "departure" : {
        "delay" : 240,
        "time" : 1380215075
      },
      "stop_id" : "6095"
    }]
  }
}]
然后,您将能够像这样迭代数据:

foreach($result[0]->trip_update->stop_time_update as $update)
{
     $time = $update->departure->time;
     ...
}
如果您无法更改数据结构,那么可能可以帮助您的是拉式解析器—该解析器不返回已解析的数据结构,而是允许您使用数据流—这样您可以迭代每个节点。我找到的唯一一个是PHP的扩展:


查看用法部分。

您应该重新编写JSON-您有多个同名键,尝试执行
打印($result)
查看我在说什么-PHP将一次又一次地覆盖“stop\u time\u update”键,您将只能访问最后一个条目。相反,您应该这样组织JSON:

[
  {
  "id" : "421356",
  "trip_update" : {
    "trip" : {
      "trip_id" : "421356",
      "start_time" : "12:05:00",
      "start_date" : "20130926",
      "route_id" : "15"
    },
    "stop_time_update" : [{
       "stop_sequence" :70,
      "departure" : {
        "delay" : 240,
        "time" : 1380215057
      },
      "stop_id" : "6090"
    }, {
       "stop_sequence" :71,
      "departure" : {
        "delay" : 240,
        "time" : 1380215075
      },
      "stop_id" : "6095"
    }]
  }
}]
然后,您将能够像这样迭代数据:

foreach($result[0]->trip_update->stop_time_update as $update)
{
     $time = $update->departure->time;
     ...
}
如果您无法更改数据结构,那么可能可以帮助您的是拉式解析器—该解析器不返回已解析的数据结构,而是允许您使用数据流—这样您可以迭代每个节点。我找到的唯一一个是PHP的扩展:


检查用法部分。

JSON
响应无效,因为它包含重复的键,但
JSON
不允许重复的键

您应该联系您试图请求此响应的服务

如果您有一个有效的
JSON
响应,那么您可以使用
JSON\u decode
函数对其进行解码,该函数返回一个对象或数组(取决于第二个参数)

您不能为此使用
JSON解析器
,因为由于相同的键,它将始终覆盖第一个元素。唯一正确的解决方案是让创建“JSON”的人修复代码,要么使用数组,要么使用具有唯一键的对象


另一个选项是编写自己的解码器函数来解析它

JSON
响应无效,因为它包含重复的键,但
JSON
不允许重复的键

您应该联系您试图请求此响应的服务

如果您有一个有效的
JSON
响应,那么您可以使用
JSON\u decode
函数对其进行解码,该函数返回一个对象或数组(取决于第二个参数)

您不能为此使用
JSON解析器
,因为由于相同的键,它将始终覆盖第一个元素。唯一正确的解决方案是让创建“JSON”的人修复代码,要么使用数组,要么使用具有唯一键的对象


另一种选择是编写自己的解码器函数来解析它

如果编写自己的解析器或使用带有回调的流解析器,可能会得到更好的结果。下面是一个用于回调的解析器的示例。因此,解析器不会将整个JSON数据读入内存,而是将数据分块读取,并在新对象启动或读取属性时通知您的“侦听器类”。通过这样做,您应该为每个
stop\u time\u update
属性获得单独的回调事件,而不是解析数组中的一个值


与XML非常相似。

如果编写自己的解析器或使用带有回调的流解析器,可能会获得更好的结果。下面是一个用于回调的解析器的示例。因此,解析器不会将整个JSON数据读入内存,而是将数据分块读取,并在新对象启动或读取属性时通知您的“侦听器类”。通过这样做,您应该为每个
stop\u time\u update
属性获得单独的回调事件,而不是解析数组中的一个值


与XML非常相似。

您好,您可以更改名称

function next_update($coincidencias){
$replace=$coincidencias[0].$GLOBALS["json_stop_time_update"]++;
return $replace;
}
$result= preg_replace_callback("/stop_time_update/","next_update",$jsondata);
$result = json_decode($result);

嗨,也许你可以换个名字

function next_update($coincidencias){
$replace=$coincidencias[0].$GLOBALS["json_stop_time_update"]++;
return $replace;
}
$result= preg_replace_callback("/stop_time_update/","next_update",$jsondata);
$result = json_decode($result);

请尝试,尽管它是有效的JSON,但第二次出现的
stop\u time\u update
将被删除(或者,如果被第二次覆盖,则是第一次),这是一个对象属性,不能定义两次。它应该是一个包含两个ObjectsHank的数组,它进行验证。我知道它进行验证,正如我在评论中提到的。关键是,它的结构很糟糕,您应该向这个JSON的提供者提及它。它可能会进行验证,但在重复的元素周围没有合适的数组结构。因此,您将丢失
json\u decode()
步骤中的数据。请尝试,尽管它是有效的json,但第二次出现的
stop\u time\u update
将被删除(或者,如果被第二次覆盖,则是第一次),它是对象属性,并且不能定义两次。它应该是一个包含两个ObjectsHank的数组,它进行验证。我知道它进行验证,正如我在评论中提到的。关键是,它的结构很糟糕,您应该向这个JSON的提供者提及它。它可能会进行验证,但在重复的元素周围没有合适的数组结构。因此,您正在丢失
json\u deco上的数据