2010-10-18 17 views
8

favor ver este código:¿Cómo funciona el operador "&" en una función de PHP?

function addCounter(&$userInfoArray) { 
    $userInfoArray['counter']++; 
    return $userInfoArray['counter']; 
} 

$userInfoArray = array('id' => 'foo', 'name' => 'fooName', 'counter' => 10); 
$nowCounter = addCounter($userInfoArray); 

echo($userInfoArray['counter']); 

Esto mostrará 11.

Pero! Si elimina el operador "&" en el parámetro de función, el resultado será 10.

¿Qué está pasando?

+0

2 respuestas perfectas para sólo 3 minutos! ¿Son genios o algo así? o esperando que haga esta pregunta. ¡Muy sorprendido! – Deckard

+0

* (relacionado) * [¿Qué significa este símbolo en PHP] (http://stackoverflow.com/questions/3737139/reference-what-does-this-symbol-mean-in-php) – Gordon

+0

Oh ... yo Intenté googlearlo, pero fallé ... Tan embarazoso ... – Deckard

Respuesta

22

El operador & le dice a PHP que no copie la matriz al pasarla a la función. En su lugar, se pasa una referencia a la matriz en la función, por lo que la función modifica la matriz original en lugar de una copia.

Basta con mirar a este mínimo ejemplo:

<?php 
function foo($a) { $a++; } 
function bar(&$a) { $a++; } 

$x = 1; 
foo($x); 
echo "$x\n";  
bar($x); 
echo "$x\n"; 
?> 

En este caso, la salida es:

1 
2 

- la llamada a foo no modificó $x. La llamada a bar, por otro lado, sí.

+0

+1 para buen ejemplo conciso – Ross

+0

Gracias por la respuesta perfecta – Deckard

+0

Sé que estoy un poco tarde en esto, pero gracias por esta respuesta extremadamente clara que no dejó nada en duda. – Michael

6

Aquí el carácter & significa que la variable se pasa por referencia , en lugar de por valor. La diferencia entre los dos es que si pasa por referencia, cualquier cambio realizado en la variable también se realiza en el original.

function do_a_thing_v ($a) { 
    $a = $a + 1; 
} 
$x = 5; 
do_a_thing_v($x); 
echo $x; // echoes 5 

function do_a_thing_r (&$a) { 
    $a = $a + 1; 
} 
$x = 5; 
do_a_thing_v($x); 
echo $x; // echoes 6 
+0

Gracias por su respuesta perfecta – Deckard

2

Al usar el ampersand antes de una variable en una llamada de función, se asocia con la variable original. Con eso, el código que publicaste dice que agregará 1 al contador de la matriz original. Sin el símbolo de unión, se necesita una copia de los datos y se agrega a él, a continuación, devuelve el nuevo contador de 11. La matriz de edad aún se mantiene intacta en 10 y la nueva variable de contador regresó convierte en 11.

http://www.phpreferencebook.com/samples/php-pass-by-reference/

es un buen ejemplo.

+0

Realmente gracias! – Deckard

2

Quizás puedo agregar a las otras respuestas que, si es un objeto, entonces no es "el objeto pasado como valor", sino que es "la referencia del objeto se pasa como un valor" (aunque estoy preguntando cuál es la diferencia entre "el objeto se pasa por referencia" vs "la referencia del objeto se pasa por valor" en los comentarios). Una matriz se pasa por valor de forma predeterminada.

información: Objects and references

Ejemplo:

class Foo { 
    public $a = 10; 
} 

function add($obj) { 
    $obj->a++; 
} 

$foo = new Foo(); 
echo $foo->a, "\n"; 

add($foo); 
echo $foo->a, "\n"; 

Resultados:

$ php try.php 
10 
11 
+0

Gracias otro Sr. Genio. – Deckard

+1

Este es un error común. Los objetos * no * se pasan por referencia. Más bien, su referencia se pasa por valor. ¡Esta es una diferencia crucial! Intente modificar la referencia en sí, en lugar de un miembro de instancia (es decir, escriba '$ obj = new Foo()' dentro del método). Irónicamente, la página que vinculó incluso * dice * que su cita no es cierta. Entonces debes haber sabido que escribiste algo falso. –

+0

si se pasa por referencia, vs si su referencia se pasa por valor, si '$ obj = new Foo()' dentro del método, ¿los resultados son los mismos? es decir, cuando se imprime una vez más, sigue siendo '11'. –

Cuestiones relacionadas