Tuve que pasar unas horas para descubrir por qué un [3] está cambiando en cada iteración. Esta es la explicación a la que llegué.
Existen dos tipos de variables en PHP: variables normales y variables de referencia. Si asignamos una referencia de una variable a otra, la variable se convierte en una variable de referencia.
por ejemplo en
$a = array('zero', 'one', 'two', 'three');
si hacemos
$v = &$a[0]
el elemento 0 ª ($a[0]
) se convierte en una variable de referencia. $v
apunta hacia esa variable; por lo tanto, si realizamos algún cambio en $v
, se reflejará en $a[0]
y viceversa.
ahora si hacemos
$v = &$a[1]
$a[1]
se convertirá en una variable de referencia y $a[0]
se convertirá en una variable normal (ya que nadie más está apuntando a $a[0]
se convierte en una variable normal. PHP es lo suficientemente inteligente como para que sea una variable normal cuando nadie más está apuntando hacia ella)
Esto es lo que sucede en el primer bucle
foreach ($a as &$v) {
}
Después de la última iteración $a[3]
es una variable de referencia.
Desde $v
está apuntando a $a[3]
cualquier cambio en $v
resulta en un cambio a $a[3]
en el segundo bucle,
foreach ($a as $v) {
echo $v.'-'.$a[3].PHP_EOL;
}
en cada iteración como $v
cambios, $a[3]
cambios. (porque $v
aún apunta a $a[3]
).Esta es la razón por la cual $a[3]
cambia en cada iteración.
En la iteración anterior a la última iteración, $v
tiene asignado el valor "dos". Dado que $v
apunta a $a[3]
, $a[3]
ahora obtiene el valor 'dos'. Mantén esto en mente.
En la última iteración, $v
(que apunta a $a[3]
) ahora tiene el valor de 'dos', porque $a[3]
se estableció en dos en la iteración anterior. two
se imprime. Esto explica por qué 'dos' se repite cuando $ v se imprime en la última iteración.
'unset ($ your_used_reference);' cada vez que utilice un 'foreach ($ var as & $ your_used_reference)'! – Wrikken
gracias por el punto, pero solo quería entender la lógica de cómo funciona el segundo foreach. – Centurion
¿Por qué $ not_used_reference (o $ v en la publicación OPs) no se desactivan automáticamente? ¿Su alcance es el foreach y no debería existir más allá? – Hurix