-1

I'm trying to understand this code :

$array = [0, 1, 2];
foreach ($array as &$val) {
    var_dump(current($array));
}

In PHP 5.6 the result would be int(1) int(2) bool(false), in PHP 7 the result would be int(0) int(0) int(0). The question is why?

Why isn't the result in both cases the values of the array 0, 1, 2? I understand that current() in PHP returns the current value, so each time the foreach goes over each one, isn't the current value that should be printed out?

IMSoP
  • 89,526
  • 13
  • 117
  • 169
  • 2
    http://php.net/manual/en/migration70.incompatible.php#migration70.incompatible.foreach – user3942918 Jan 02 '19 at 15:58
  • @PaulCrovella you just linked what I don't understand ;-) Care to explain please? I don't understand what's in the doc. –  Jan 02 '19 at 15:59
  • From the docs: _The end of an array and the result of calling current() on an empty array are indistinguishable from a boolean FALSE element. To properly traverse an array which may contain FALSE elements, see the foreach() function. To still use current() and properly check if the value is really an element of the array, the key() of the current() element should be checked to be strictly different from NULL. _ – Sfili_81 Jan 02 '19 at 15:59
  • @gumakettell The answer is in the link, "_Prior to PHP 7, the internal array pointer was modified while an array was being iterated over with foreach. This is no longer the case ..._" – GrumpyCrouton Jan 02 '19 at 15:59
  • + http://php.net/manual/en/control-structures.foreach.php (first "Note" section) – user1597430 Jan 02 '19 at 16:00
  • @GrumpyCrouton as I said, I don't understand what's in the link x) The English it's written in is too much for me to understand. I'm not dumb, I can read what's written. When I asked the question it was to get a better explanation than the 2 lines written in the mentioned doc. –  Jan 02 '19 at 16:02
  • 2
    Just use $val and keep your code simple. – asiby Jan 02 '19 at 16:03
  • @gumakettell Okay well, prior to PHP 7, foreach modified the internal array pointer to match which iteration it was on, it no longer does that. `current()` returns "_the current element in an array_", which is specified by the internal array pointer, so prior to PHP 7, this pointer would change, but it no longer does, so `current()` always returns the same thing (inside a foreach, given you haven't changed the pointer yourself). There isn't really much more you can add to the description, maybe you should research what an internal array pointer is? – GrumpyCrouton Jan 02 '19 at 16:07
  • like @user1597430 says : _In PHP 7, foreach does not use the internal array pointer_ so in your var_dump(current($array)); always return the first element – Sfili_81 Jan 02 '19 at 16:09

1 Answers1

4

The implementation of foreach was changed in PHP 7.0 as described in this migration note:

Prior to PHP 7, the internal array pointer was modified while an array was being iterated over with foreach. This is no longer the case.

The current() function returns the element pointed at by the "internal array pointer", a concept from older versions of PHP which is rarely used in modern code. This can be used as an alternative looping mechanism with the each() function which is deprecated in PHP 7.2.

In older versions of PHP, each() and foreach both changed this "internal array pointer", so you could mix foreach and current as shown in the example. However, this meant the internal code was unnecessarily complicated and slow for some cases, so it was changed in PHP 7.0. Now, foreach tracks its position in the array in a different way, which current() does not read.

IMSoP
  • 89,526
  • 13
  • 117
  • 169