La nueva versión de PHP7 ya está aquí, y esta nueva versión introduce cambios no compatibles a la sentencia foreach. Así como detallamos gran parte de las nuevas funcionalidades y detalles de compatibilidad en el anterior post PHP7 ya está aquí, en este post vamos a centrarnos de manera detallada en los cambios sobre la sentencia foreach.

El puntero al array no se modifica dentro de la sentencia

Dentro de una sentencia foreach el puntero al array no será modificado. Por tanto, si has utilizado funciones como current dentro de esta sentencia, tendrás que tener en cuenta esto a la hora de migrar proyectos a PHP7. Veámoslo con un ejemplo.

<?php
$values = [1, 2, 3];

foreach ($values as &$value) {
    var_dump(current($values));
}

En PHP5, la salida del código anterior sería:

int(2)
int(3)
bool(false)

En cambio, en PHP7 la salida sería:

int(1)
int(1)
int(1)

Comportamiento del foreach por referencia mejorado

Si dentro de una sentencia foreach por referencia añadimos elementos al array, estos elementos serán iterados.

<?php
$values = [1];

foreach ($values as &$value) {
    var_dump($value);
    $values[1] = 2;
}

En PHP5, la salida del código anterior sería:

int(1)

En cambio, en PHP7:

int(1)
int(2)

Hay que ir con mucho cuidado, porque algunos foreach ya desarrollados podrían causar bucles infinitos en PHP7.

El cambio retrocompatible que se han dejado

A pesar de haber introducido mejoras, no han solucionado un problema muy básico de alcances. La sentencia foreach se deja definida la variable con el último valor iterado. Creo que deberían haber roto este comportamiento extraño, ya que no tiene ningún sentido acceder a esa variable de ese modo, y simplemente no debería estar definida, como en el resto de lenguajes.

<?php
$values = [1];

foreach ($values as $value) {
}

echo $value;

El código anterior en ambas versiones funciona y escribiría 1, cosa no deseable en mi opinión.