2010-12-29 23 views
12

¿Cuál es la diferencia entre

foreach ($my_array as $my_value) { 
} 

Y:

foreach ($my_array as &$my_value) { 
} 

?

¿Puedo pedirle que me brinde dos ejemplos reales de cuándo usar uno y cuándo usa el otro?

+1

Como regla general, nunca utilice referencias. – troelskn

+4

@troelskn: Esa es una regla de oro estúpida. A veces tienes que usarlos. Si no sabe si debe usarlos, entonces probablemente no sea necesario. Pero cuando quiera modificar el valor real, debe usar referencias. –

+0

@Felix Kling: estoy de acuerdo con @troelskn. Nunca tuve la necesidad de modificar el valor real de una matriz. Cada vez que tuve que hacerlo, puede hacer mucho mejor código que usar ('& $ var'). La única forma en que puedo pensar puede ser ... optimización: si usas '&', supongo (corrígeme si me equivoco) que no hay necesidad de hacer una copia en una variable temporal. Por lo tanto, ganancia de tiempo de ejecución. Si tiene un ejemplo en el que no puede evitar bucles como el que tiene el '&' en mi pregunta, ¿puedo pedirle que los muestre como un comentario aquí? ¡Muchas gracias! –

Respuesta

21

El primer ejemplo crea una copia del valor, mientras que el segundo usa una referencia al valor original. Por lo tanto, después de la ejecución de la primera foreach, la matriz original sigue intacta. Después del segundo foreach, el conjunto original podría haberse modificado ya que se manejó por referencia.

Algunas funciones PHP nativas ya funcionan de esta manera, como shuffle() que reorganiza el contenido de su matriz. Se dará cuenta de que esta función no devuelve una matriz, que acaba de llamar que:

$myArray = array('foo', 'bar', 'fizz', 'buzz'); 
shuffle($myArray); 
// $myArray is now shuffled 

y funciona su magia, ya que trabaja con la matriz por referencia en lugar de crear una copia de la misma.

Entonces hay funciones que no pasa nada por referencia sino que tienen que ver con una copia del valor original, como ucwords() que devuelve la nueva cadena resultante:

$myString = "hello world"; 
$myString = ucwords($myString); 
// $myString is now capitalized 

Ver Passing by Reference.

+2

si $ my_value es un objeto, inevitablemente pasó por referencia. – Epharion

+1

@Epharion: No, PHP siempre pasa por val a menos que se le indique que pase por ref. Y los objetos no son una excepción a esto. Solo con objetos, un pase por val se realiza de manera muy similar a un pase por ref debido a la forma en que PHP almacena los objetos;) – NikiC

5

Jonathan's answers lo describe muy bien. Simplemente para la corrección, aquí están sus dos ejemplos:

  1. valores simplemente leyendo:

    $my_array = range(0,3); 
    foreach ($my_array as $my_value) { 
        echo $my_value . PHP_EOL; 
    } 
    
  2. Adición de un número a cada elemento (por lo tanto modifican cada valor):

    foreach ($my_array as &$my_value) { 
        $my_value += 42; 
    } 
    

    Si no usa &$my_value, la adición no tendrá ningún efecto en $my_array. Pero se podría escribir las mismas que no utilizan referencias:

    foreach($my_array as $key=>$value) { 
        $my_array[$key] = $value + 42; 
    } 
    

    La diferencia es que estamos accediendo/cambiar el valor original directamente con $my_array[$key].

DEMO

+0

Muchas gracias, sus ejemplos son tan claros como el agua. –

0

Cuando el prefijo de una variable con un símbolo de unión, que está creando una “referencia”. Referencias en PHP son como accesos directos o enlaces simbólicos en el equipo. Puede crear una variable de puntero que sea solo otro nombre para la misma información.

No veo una gran diferencia en el uso de estos, excepto que NO COPIAS una memoria de ahorro variable. Cuando está pasando variables, puede pasar la referencia y los puntos de referencia al objeto original.

+0

Un error típico de principiante: pensar que PHP es estúpido. PHP no copia ciegamente los valores. Utiliza el concepto de copiar sobre escritura, es decir, que el valor solo se copia cuando se lo cambia. La creación de referencias por motivos de rendimiento normalmente solo es contraproducente, ya que a menudo hace que PHP haga solo más copias. – NikiC

0

Un ejemplo del mundo real para & uso es cuando se necesita para cambiar el contenido de una matriz con muy pocas líneas de código

foreach($arrFeed as &$objFeed) 
    $objFeed['externalSrc'] = convertToLocalImage($objFeed['externalSrc']); 
Cuestiones relacionadas