Edward
Edward

Reputation: 9778

How to use foreach when there is no array in the object?

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!

Upvotes: 0

Views: 121

Answers (2)

Elias Van Ootegem
Elias Van Ootegem

Reputation: 76413

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);
}

Upvotes: 1

klkvsk
klkvsk

Reputation: 670

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...

Upvotes: 2

Related Questions