Reputation: 8548
I have this problem where an API responds to me with DEPARTURESEGMENT sometimes containing only one object, and sometimes containing an array of objects. Depending on which case it is, I seem to need different logics in my foreach-loop.
Response A:
{
"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"
}
}
}
]
}
}
Works with this loop:
foreach ($apiData->getdeparturesresult->departuresegment as $m) {
While this response B:
{
"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"
}
}
}
}
}
needs a loop like this (otherwise it throws an error):
foreach ($apiData->getdeparturesresult as $m) {
Is there a way to write the loop failsafe for whether DEPARTURESEGMENT is an array of objects or just one object (the brackets [] is the only difference to the structure of the json right?) or do I have to somehow test and see first whether DEPARTURESEGMENT is an array or not, and dispatch to two different loops depending on the outcome?
Upvotes: 1
Views: 104
Reputation: 214969
I have this little useful function in my standard repertoire:
function iter($x) {
if(is_array($x))
return $x;
if(is_object($x)) {
if($x instanceof \Iterator)
return $x;
if(method_exists($x, 'getIterator'))
return $x->getIterator();
return get_object_vars($x);
}
return array($x);
}
This way you can use any variable with foreach
without having to check it beforehand:
foreach(iter($whatever) as $item)
...
Upvotes: 1
Reputation: 9910
You have a few methods that can help you:
In you situation, you would probably be fine by doing the following:
if (is_object($entry)) {
handleObject($entry);
} elseif (is_array($entry) && count($entry)) {
foreach ($entry as $e) {
handleObject($e);
}
}
Upvotes: 1
Reputation: 1720
How about checking whether it's an array or not with is_array? I made a simple example of it's usage here - http://codepad.org/WNjbIPZF
Upvotes: 0