У меня есть эта проблема, когда API отвечает мне, когда DEPARTURESEGMENT иногда содержит только один объект и иногда содержит массив объектов. В зависимости от того, в каком случае это, мне кажется, нужны разные логики в моей петле foreach.
Ответ 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" } } } ] } }
Работает с этим циклом:
foreach ($apiData->getdeparturesresult->departuresegment as $m) {
Хотя этот ответ 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" } } } } }
нужен такой цикл (иначе он выдает ошибку):
foreach ($apiData->getdeparturesresult as $m) {
Есть ли способ написать цикл безотказным для того, является ли DEPARTURESEGMENT массивом объектов или только одним объектом (скобки [] – это единственное отличие от структуры json?) Или мне нужно как-то проверить и сначала увидеть, DEPARTURESEGMENT – массив или нет, и отправка в два разных цикла в зависимости от результата?
У вас есть несколько способов, которые могут вам помочь:
В вашей ситуации вы, вероятно, будете в порядке, выполнив следующее:
if (is_object($entry)) { handleObject($entry); } elseif (is_array($entry) && count($entry)) { foreach ($entry as $e) { handleObject($e); } }
У меня есть эта небольшая полезная функция в моем стандартном репертуаре:
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); }
Таким образом, вы можете использовать любую переменную с foreach
без предварительной проверки:
foreach(iter($whatever) as $item) ...
Как насчет проверки того, массив или нет с is_array ? Я сделал простой пример его использования здесь – http://codepad.org/WNjbIPZF