dannymcgee
dannymcgee

Reputation: 673

PHP key() returning the key for the next item in the array, not the current one

The code here is pretty simple, so I'm not sure what could be happening. This site that I made a couple of years ago has been working fine the whole time, and today I randomly checked on it to find it completely borked. I'm not sure if it was a PHP upgrade performed by my webhost or maybe an automatic WordPress update that broke it, but in any case, the code is not behaving as expected.

In the WordPress loop, for each post, this code is running:

$stats = array(
    'recon' => 'Recon',
    'inf' => 'Infantry',
    'fist' => 'Fire Support',
    'atgm' => 'ATGM',
    'armor' => 'Armor',
    'arty' => 'Artillery',
    'aa' => 'Anti-Air',
    'air' => 'Aircraft',
    'heli' => 'Helicopters'
);

foreach( $stats as $stat_name ):
    $stat_key = key( $stats );

    // DEBUG:
    echo '<p>' . $stat_key . ' : ' . $stat_name . '</p>';

    ...
    next( $stats );
endforeach;

As you can see on the live site, key( $stats ) is returning the key for the next item in the array and not the current one, and returning null for the last item in the array. What could possibly be going wrong here?

Upvotes: 0

Views: 24

Answers (1)

ArtisticPhoenix
ArtisticPhoenix

Reputation: 21671

Simply make use of the key option in the foreach

 foreach( $stats as $key => $stat_name ):

   // DEBUG:
   echo '<p>' . $stat_key . ' : ' . $stat_name . '</p>';

endforeach;

I wouldn't suggest calling, next while in a foreach loop, it will do the iteration for you. Likely it's already done so when you call key, because its moved the pointer on to the next item already.

Foreach can do weird things when you mess with the structure of the array because it creates a shadow copy of the array (I forget the exact way its explained, and they may have changed it somewhat in 7). In any case, I'm not sure what affect calling next will have, maybe none, because of the way that it handles iterating with foreach. I never tried it!

If you want to use next, then use the do or while loop.

The really proper syntax would be

foreach( $stats as $key => $stat_name ){
   // DEBUG:
   echo '<p>' . $stat_key . ' : ' . $stat_name . '</p>';
}

The Alternative syntax is useful if you have it in html, such as

<?php foreach( $stats as $key => $stat_name ): ?>
     <p><?=$stat_key;?> : <?=$stat_name;?></p>
<?php endforeach; ?>
<div> ....

This is because the endforeach; is more descriptive then the } and it can be very easy to lose track of the } when mixed with HTML and other control structures (like if statements). With the alternative statement you wind up with things like endforeach; endif; instead of } } . Hope that makes sense.

Upvotes: 2

Related Questions