2
<?php
$a = array(1, 2, 3, 4, 5);
foreach ($a as $key => $elem) {
    echo "$key = $elem"; echo ' = ';
    var_dump(current($a));\
}
?>

The output I get when running that is as follows:

0 = 1 = int(2)

1 = 2 = int(2)

2 = 3 = int(2)

3 = 4 = int(2)

4 = 5 = int(2)

Seems to me that this is the output I should be getting?:

0 = 1 = int(1)

1 = 2 = int(2)

2 = 3 = int(3)

3 = 4 = int(4)

4 = 5 = int(5)

I do current() before the for loop on $a and get int(1). Thus it seems like it's the foreach loop that's causing it to increment. But if that's the case why is it only doing it once?

If I call next() in the for loop it increments but not otherwise. Of course next() starts out at int(3) (ie. the value after int(2))..

neubert
  • 15,947
  • 24
  • 120
  • 212

3 Answers3

1

From reading the PHP documention on current, it does not look like you should expect foreach to move the current pointer.

Please see: http://php.net/manual/en/function.current.php

What's a bit confusing is that the each function does move the current pointer. So if you rewrite your array as a loop using each rather than foreach, then you will get the desired current behavior.

Here's your example rewritten with each(), which produces the expected results:

<?php
$a = array(1, 2, 3, 4, 5);
while ( list($key,$elem) = each($a)) {
    echo "$key = $elem"; echo ' = ';
    var_dump(current($a));
}
?>
RonaldBarzell
  • 3,822
  • 1
  • 16
  • 23
  • 1
    Yeah - that's what's confusing me - the fact that foreach does seem to be incrementing the pointer but only once. Seems to me that it should increment it every time or not at all. – neubert Dec 12 '12 at 14:43
0

current() uses the internal flag (pointer) and foreach uses it's own.

If you want to do this (which is kind of silly as you have the key in $key) you can use ArrayIterator

Niclas Larsson
  • 1,317
  • 8
  • 13
  • Why, then, is current() saying int(2) instead of int(1) the whole time? As for why I'm doing current()... I believe it better illustrates the unexpected way the internal flag is behaving than next() or prev() does. – neubert Dec 12 '12 at 14:41
0

I just stumbled on the same problem, and I believe I have a theory. Foreach doesn't access the array elements by value, it creates its own copy. However, while doing this, it increments the value returned by current() just once.

To check this:

<?php

$a = [0, 1, 2];
    foreach ($a as &$val){ // accessing the array elts by reference this time
    var_dump(current($a));
}

/*this outputs:
int(1)
int(2)
bool(false)*/