2011-02-11 39 views
28
<?php 
    $a = array('a', 'b', 'c', 'd'); 

    foreach ($a as &$v) { } 
    foreach ($a as $v) { } 

    print_r($a); 
?> 

creo que es un programa normal, pero esta es la salida que estoy recibiendo:comportamiento extraño del foreach

Array 
(
    [0] => a 
    [1] => b 
    [2] => c 
    [3] => c 
) 

Por favor alguien puede explicar esto a mí?

+4

¿Qué significa * "creo que es normal, pero la web lo vi op ......... entonces ... ahh wat is it" * mean? –

+0

¡Me lo estoy preguntando! ¿Por qué obtener este resultado? :) –

+1

@Bart Kiers: Parece aturdido. – BoltClock

Respuesta

67

Este comportamiento PHP está bien documentada Ver la warning en la página foreach de php.net

Advertencia

de referencia de un valor de $ y el último elemento de la matriz permanecerá incluso después del foreach loop. Se recomienda destruirlo por unset().

$a = array('a', 'b', 'c', 'd'); 

foreach ($a as &$v) { } 
unset($v); 
foreach ($a as $v) { } 

print_r($a); 

EDITAR

Intento de una guía paso a paso a lo que realmente está pasando aquí

$a = array('a', 'b', 'c', 'd'); 
foreach ($a as &$v) { } // 1st iteration $v is a reference to $a[0] ('a') 
foreach ($a as &$v) { } // 2nd iteration $v is a reference to $a[1] ('b') 
foreach ($a as &$v) { } // 3rd iteration $v is a reference to $a[2] ('c') 
foreach ($a as &$v) { } // 4th iteration $v is a reference to $a[3] ('d') 

          // At the end of the foreach loop, 
          // $v is still a reference to $a[3] ('d') 

foreach ($a as $v) { } // 1st iteration $v (still a reference to $a[3]) 
          // is set to a value of $a[0] ('a'). 
          // Because it is a reference to $a[3], 
          // it sets $a[3] to 'a'. 
foreach ($a as $v) { } // 2nd iteration $v (still a reference to $a[3]) 
          // is set to a value of $a[1] ('b'). 
          // Because it is a reference to $a[3], 
          // it sets $a[3] to 'b'. 
foreach ($a as $v) { } // 3rd iteration $v (still a reference to $a[3]) 
          // is set to a value of $a[2] ('c'). 
          // Because it is a reference to $a[3], 
          // it sets $a[3] to 'c'. 
foreach ($a as $v) { } // 4th iteration $v (still a reference to $a[3]) 
          // is set to a value of $a[3] ('c' since 
          //  the last iteration). 
          // Because it is a reference to $a[3], 
          // it sets $a[3] to 'c'. 
+0

lo sé !!! ¿Pero qué está mal en mi programa? –

+3

@Manish Trivedi: consulta la parte ** Advertencia ** sobre por qué ocurre esto. No hay nada malo con tu programa. – BoltClock

+0

Gracias ..... lo tengo –

2

El primer bucle foreach no hace ningún cambio en el array, tal como lo esperaríamos. Sin embargo, se debe asignar a $v una referencia a cada uno de los elementos de $a, , de modo que, cuando finaliza el primer ciclo, $v es, de hecho, una referencia a $a[2].

Tan pronto como se inicia el segundo ciclo, $v ahora tiene asignado el valor de cada elemento . Sin embargo, $v ya es una referencia a $a[2];, por lo tanto, cualquier valor asignado se copiará automáticamente en el último elemento de la matriz.

Por lo tanto, durante la primera iteración, $a[2] se convertirá en cero, luego en uno, y luego una vez más, siendo efectivamente copiado en sí mismo. Para resolver este problema, siempre debe desarmar las variables que utiliza en los bucles by-reference foreach forech o, mejor aún, evitar usar el anterior por completo.