这个帖子讨论是这样做还是那样做。事实是,没有另一个是不充分的。解决方案(以及对问题的更清晰描述)可以在这里找到:
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-&gt;离开不存在。但是为什么那时候甚至会存在??
-----更新-------
当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子句来测试是否实际需要循环(从而使得在循环和外部获取我想要的值的逻辑加倍)?
答案 0 :(得分:0)
$m
departure
。你正在循环通过departuresegment
的每个元素。所以首先$m
是departure
然后是direction
,然后是segmentid
。你可能只想要
foreach ($apiData->getdeparturesresult->departuresegment as $m)
<强> TEST 强>
$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"}}}}}';
$apiData = json_decode($json);
foreach ($apiData->getdeparturesresult->departuresegment as $key => $m) {
echo "key:" . $key . "\r\n";
echo '$m:' . print_r($m, true);
echo "\r\n";
}
<强>输出强>
key:departure
$m:stdClass Object
(
[location] => stdClass Object
(
[@id] => 7461018
[@x] => 12.523958
[@y] => 57.938402
[name] => Noltorps centrum
)
[datetime] => 2014-12-04 23:05
)
key:direction
$m:Alingsås station
key:segmentid
$m:stdClass Object
(
[mot] => stdClass Object
(
[@displaytype] => B
[@type] => BLT
[#text] => Buss
)
[carrier] => stdClass Object
(
[name] => Västtrafik
[url] => http://www.vasttrafik.se/
[id] => 279
[number] => 1
)
)
只有第一个有日期时间......