【发布时间】:2015-02-02 23:14:48
【问题描述】:
这个帖子讨论是这样还是那样做。事实是没有另一个是不够的。可以在此处找到解决方案(以及对问题的更清晰描述):
how to iterate over JSON property not knowing if it's array or not?
我将以下 JSON 解析为对象 (stdClass):
{
"getdeparturesresult":{
"departuresegment":{
"departure":{
"location":{
"@id":"7461018",
"@x":"12.523958",
"@y":"57.938402",
"name":"Noltorps centrum"
},
"datetime":"2014-12-04 23:05"
},
"direction":"Alingsås station",
"segmentid":{
"mot":{
"@displaytype":"B",
"@type":"BLT",
"#text":"Buss"
},
"carrier":{
"name":"Västtrafik",
"url":"http://www.vasttrafik.se/",
"id":"279",
"number":"1"
}
}
}
}
}
在 XML 中也是如此,更具可读性,但无法在我的 var_dump 中漂亮地打印出这么好的 JSON...
<getdeparturesresult>
<departuresegment>
<departure>
<location id="7461018" x="12.523958" y="57.938402">
<name>Noltorps centrum</name>
</location>
<datetime>2014-12-04 23:05</datetime>
</departure>
<direction>Alingsås station</direction>
<segmentid>
<mot displaytype="B" type="BLT">Buss</mot>
<carrier>
<name>Västtrafik</name>
<url>http://www.vasttrafik.se/</url>
<id>279</id>
<number>1</number>
</carrier>
</segmentid>
</departuresegment>
</getdeparturesresult>
我用这段代码遍历它...
$r=array();
$i=0;
foreach ($apiData->getdeparturesresult->departuresegment as $m) {
$r[$i]["depTime"] = $m->departure->datetime; //tid för avgången
$segmentid = get_object_vars($m->segmentid->mot);
$r[$i]["typText"] = $segmentid['#text'];
//$r[$i]["typ"] = $segmentid['@displaytype'];
$r[$i]["nr"] = $m->segmentid->carrier->number;
$r[$i]["destination"] = $m->direction; //slutstation (som står på bussen, tåget etc.)
$r[$i]["operator"] = $m->segmentid->carrier->name;
$i++;
}
...它运行良好,直到我得到这样的响应,其中只有一个 DEPARTURE 元素,在这种情况下,我会抛出这个错误:
(http500) Notice: Undefined property: stdClass::$departure
所以在我看来,循环尝试第二次运行,在第一行失败
$r[$i]["depTime"] = $m->departure->datetime; //tid för avgången
因为 $m->departure 不存在。但那为什么 $m 会自己存在呢?
----- 更新 -------
这是当 DEPARTURESEGMENT 中有多个项目时 JSON 的样子:
{
"getdeparturesresult":{
"departuresegment":[{
"departure":{
"location":{
"@id":"7461018",
"@x":"12.523958",
"@y":"57.938402",
"name":"Noltorps centrum"
},
"datetime":"2014-12-04 23:05"
},
"direction":"Alingsås station",
"segmentid":{
"mot":{
"@displaytype":"B",
"@type":"BLT",
"#text":"Buss"
},
"carrier":{
"name":"Västtrafik",
"url":"http://www.vasttrafik.se/",
"id":"279",
"number":"1"
}
}
},
{
"departure":{
"location":{
"@id":"7461018",
"@x":"12.523958",
"@y":"57.938402",
"name":"Noltorps centrum"
},
"datetime":"2014-12-04 23:05"
},
"direction":"Alingsås station",
"segmentid":{
"mot":{
"@displaytype":"B",
"@type":"BLT",
"#text":"Buss"
},
"carrier":{
"name":"Västtrafik",
"url":"http://www.vasttrafik.se/",
"id":"279",
"number":"1"
}
}
}
]
}
}
在这种情况下,我的循环工作正常。但是,当只有一个项目时,我需要一个像 @chiliNUTS 这样描述的循环,在 foreach 条件下更浅一层。
有没有办法编写一个循环,如果它是一个数组,它将遍历 DEPARTURESEGMENT 中的一个对象数组,如果不是,则只从第一个对象中提取值?我是否必须在循环之前放置一个单独的 if 子句来测试是否真的需要循环(从而在循环内和循环外加倍获取我想要的值的逻辑)?
【问题讨论】:
-
But why then would $m even exist itself?它将遍历对象的属性。看看pastebin.com/pUv2eAgK你就明白了。 -
是的,但它应该通过 DEPARTURESEGMENTs 对吗?而且只有其中之一。
-
循环会经过
departure、direction等等。所以,$m里面不会有departure,因为在第一个循环中它已经是departure -
如果离开段总是settet
$m默认是一个空的stdclass,如果你把项目放在上面它会变成一个数组如果有多个元素,如果不,它是一个标准类 - 因为你的错误表明离开元素不存在,是什么持有整个$apiData->getdeparturesresult->departuresegment元素? - 无论如何,如果您的元素是标准类,您可以在 foreach 循环之前检查,否则设置$apiData->getdeparturesresult->departuresegment = array($apiData->getdeparturesresult->departuresegment)
标签: php json parsing loops stdclass