0

I was using this successfully, so I thought:

foreach ($trip->STOPS->STOP as $key=>$value) {

Most of the time the data looks like this:

  ["STOPS"]=>
  object(stdClass)#247 (1) {
    ["STOP"]=>
    array(4) {
      [0]=>
      object(stdClass)#248 (2) {
        ["NAME"]=>
        string(11) "Short Hills"
        ["TIME"]=>
        string(20) "7/30/2013 6:38:24 AM"
      }
      [1]=>
      object(stdClass)#249 (2) {
        ["NAME"]=>
        string(8) "Millburn"
        ["TIME"]=>
        string(20) "7/30/2013 6:41:24 AM"
      }
      [2]=>
      object(stdClass)#250 (2) {
        ["NAME"]=>
        string(19) "Newark Broad Street"
        ["TIME"]=>
        string(20) "7/30/2013 6:53:00 AM"
      }
      [3]=>
      object(stdClass)#251 (2) {
        ["NAME"]=>
        string(21) "New York Penn Station"
        ["TIME"]=>
        string(20) "7/30/2013 7:13:00 AM"
      }
    }
  }
}

However the above PHP code caused a problem when STOP didn't contain an array of elements, when it looked like this:

  ["STOPS"]=>
  object(stdClass)#286 (1) {
    ["STOP"]=>
    object(stdClass)#287 (2) {
      ["NAME"]=>
      string(21) "New York Penn Station"
      ["TIME"]=>
      string(20) "7/30/2013 8:13:00 AM"
    }
  }
}

So as you might guess, the instead of it making $key=>$value to be the array element and the array of the NAME/TIME, it was making $key to be NAME or TIME, which is wrong of course.

How can I use this foreach method properly without having to check to see if foreach $trip->STOPS->STOP contains an array or more than one element?

The source of this data is from a SOAP request which is returned as JSON.

Or is my approach here totally wrong? If so, please kindly enlighten me? Thanks!

8
  • 1
    The clue is in the manual. foreach works only on arrays and objects if you do not have an array or an object to iterate over then do not use foreach Commented Aug 1, 2013 at 15:25
  • Are you getting results from a database? ... The reason that I ask is that you could apply a bit of a dirty hack whereby you manipulate the query. Commented Aug 1, 2013 at 15:26
  • 1
    Have you even tried your code? because it should work just fine. All objects can be iterated over using a foreach loop, even custom objects (albeit you'll only see the public properties). Besides, if you're more comfortable with an array: $arr = (array) $someObject; is possible (casting objects to array) Commented Aug 1, 2013 at 15:28
  • @Anigel Thanks for the reply. But it doesn't send back output the same each time from this SOAP request I'm doing, so I won't know if it is arrays or just a pointer to a single object (lack a better term for this). Commented Aug 1, 2013 at 15:28
  • You can still use if (is_array()) to find out if that is an array and use foreach or do something different if it is not. Commented Aug 1, 2013 at 15:29

2 Answers 2

2

You're dealing with different type of structures. You should ensure that $trip->STOPS->STOP is an array or else make it an array. Like so:

if (is_array($trip->STOPS->STOP)) {
    $stopArray = $trip->STOPS->STOP;
} else {
    // wrap it in array with single element
    $stopArray = array( $trip->STOPS->STOP );
}
foreach ($stopArray as $key=>$value) {
    // your code...
Sign up to request clarification or add additional context in comments.

Comments

1

If the value of the STOP property is either an array, containg several stdClass instances, or a single instance of stdClass, you can simply check that, and reassign the property:

if ($trip->STOPS->STOP instanceof stdClass)
{
    $trip->STOPS->STOP = array($trip->STOPS->STOP);
}
foreach($trip->STOPS->STOP as $key => $object)
{
    echo $key, implode(',', (array) $object);
}

What I've done is simply check: is STOP an array, then I change nothing, is it an instance of stdClass, I create a wrapper-array, that contains that very object, so the value of $key will always be what it needs to be.

However, since you're looping over those objects, to treat them one by one (I guess), it would be far better to create a function:

function todoWhatYouDoInLoop(stdClass $object)
{
    //do stuff
    //in case the objects are altered:
    return $object;
}

Which you can use like so:

if (is_array($trip->STOPS->STOP))
{
    $trip->STOPS->STOP = array_map('todoWhatYouDoInLoop', $trip->STOPS->STOP);
}
else
{
    $trip->STOPS->STOP = todoWhatYouDoInLoop($trip->STOPS->STOP);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.