Buscar..


Sintaxis

  • $foo = 1; $bar = &$foo; // both $foo and $bar point to the same value: 1
  • $var = 1; function calc(&$var) { $var *= 15; } calc($var); echo $var;

Observaciones

Al asignar dos variables por referencia, ambas variables apuntan al mismo valor. Tomemos el siguiente ejemplo:

$foo = 1;
$bar = &$foo;

$foo no apunta a $bar . $foo y $bar apuntan al mismo valor de $foo , que es 1 . Para ilustrar:

$baz = &$bar;
unset($bar);
$baz++;

Si tuviéramos points to relación, esto se rompería ahora después de unset() ; en cambio, $foo y $baz siguen apuntando al mismo valor, que es 2 .

Asignar por referencia

Esta es la primera fase de referencia. Esencialmente, cuando asigna por referencia , está permitiendo que dos variables compartan el mismo valor como tal.

$foo = &$bar;

$foo y $bar son iguales aquí. No se apuntan el uno al otro. Señalan al mismo lugar ( el "valor" ).


También puede asignar por referencia dentro de la construcción del lenguaje array() . Si bien no es estrictamente una asignación por referencia.

$foo = 'hi';
$bar = array(1, 2);
$array = array(&$foo, &$bar[0]);

Tenga en cuenta , sin embargo, que las referencias dentro de matrices son potencialmente peligrosas. Hacer una asignación normal (no por referencia) con una referencia en el lado derecho no convierte el lado izquierdo en una referencia, pero las referencias dentro de las matrices se conservan en estas asignaciones normales. Esto también se aplica a las llamadas de función donde la matriz se pasa por valor.

La asignación por referencia no solo se limita a las variables y matrices, sino que también están presentes para las funciones y todas las asociaciones "paso por referencia".

function incrementArray(&$arr) {
    foreach ($arr as &$val) {
        $val++;
    }
}

function &getArray() {
    static $arr = [1, 2, 3];
    return $arr;
}

incrementArray(getArray());
var_dump(getArray()); // prints an array [2, 3, 4]

La asignación es clave dentro de la definición de la función anterior. No puede pasar una expresión por referencia, solo un valor / variable. De ahí la instanciación de $a en la bar() .

Devolución por referencia

Ocasionalmente, llega un momento para que usted pueda regresar implícitamente por referencia.

Devolver por referencia es útil cuando desea utilizar una función para encontrar a qué variable debe enlazarse una referencia. No utilice el retorno por referencia para aumentar el rendimiento. El motor automáticamente optimizará esto por su cuenta. Solo devuelva las referencias cuando tenga una razón técnica válida para hacerlo.

Tomado de la documentación de PHP para devolver por referencia .

Hay muchas formas diferentes que puede tomar devolver por referencia, incluido el siguiente ejemplo:

function parent(&$var) {
    echo $var;
    $var = "updated";
}

function &child() {
    static $a = "test";
    return $a;
}

parent(child()); // returns "test"
parent(child()); // returns "updated"

La devolución por referencia no solo se limita a las referencias de funciones. También tiene la capacidad de llamar implícitamente a la función:

function &myFunction() {
    static $a = 'foo';
    return $a;
}

$bar = &myFunction();
$bar = "updated"
echo myFunction();

No puede hacer referencia directamente a una llamada de función, debe asignarse a una variable antes de utilizarla. Para ver cómo funciona, simplemente intente echo &myFunction(); .


Notas

  • Es necesario que especifique una referencia ( & ) en los dos lugares en los que pretende usarla. Eso significa, para su definición de función ( function &myFunction() {... ) y en la referencia de llamada ( function callFunction(&$variable) {... o &myFunction(); ).
  • Solo puedes devolver una variable por referencia. De ahí la instanciación de $a en el ejemplo anterior. Esto significa que no puede devolver una expresión, de lo contrario se generará un error PHP E_NOTICE ( Notice: Only variable references should be returned by reference in ...... ).
  • El retorno por referencia tiene casos de uso legítimos, pero debo advertir que deben usarse con moderación, solo después de explorar todas las demás opciones posibles para lograr el mismo objetivo.

Pasar por referencia

Esto le permite pasar una variable por referencia a una función o elemento que le permite modificar la variable original.

El paso por referencia no se limita solo a las variables, lo siguiente también se puede pasar por referencia:

  • Nuevas declaraciones, por ejemplo, foo(new SomeClass)
  • Referencias devueltas desde funciones

Arrays

Un uso común de "pasar por referencia" es modificar los valores iniciales dentro de una matriz sin llegar al extremo de crear nuevas matrices o ensuciar su espacio de nombres. El paso por referencia es tan simple como precediendo / prefijando la variable con un & => &$myElement .

A continuación se muestra un ejemplo de cómo aprovechar un elemento de una matriz y simplemente agregar 1 a su valor inicial.

$arr = array(1, 2, 3, 4, 5);

foreach($arr as &$num) {
    $num++;
}

Ahora, cuando aproveche cualquier elemento dentro de $arr , el elemento original se actualizará a medida que se incrementa la referencia. Puedes verificar esto por:

print_r($arr);

Nota

Debe tomar nota al utilizar el pase por referencia dentro de los bucles. Al final del bucle anterior, $num todavía contiene una referencia al último elemento de la matriz. ¡Asignarlo a un bucle posterior terminará manipulando el último elemento de la matriz! Puede asegurarse de que esto no suceda unset() después del bucle:

$myArray = array(1, 2, 3, 4, 5);

foreach($myArray as &$num) {
   $num++;
}
unset($num);

Lo anterior asegurará que no se encuentre con ningún problema. Un ejemplo de los problemas que podrían relacionarse con esto está presente en esta pregunta en StackOverflow .


Funciones

Otro uso común para pasar por referencia es dentro de las funciones. Modificar la variable original es tan simple como:

$var = 5;
// define
function add(&$var) {
    $var++;
}
// call
add($var);

Lo cual se puede verificar haciendo echo de la variable original.

echo $var;

Existen varias restricciones en cuanto a las funciones, como se indica a continuación en la documentación de PHP:

Nota: No hay ningún signo de referencia en una llamada de función, solo en las definiciones de función. Las definiciones de funciones solas son suficientes para pasar correctamente el argumento por referencia. A partir de PHP 5.3.0, recibirá una advertencia que dice que el "paso por referencia en tiempo de llamada" está en desuso cuando usa & in foo (& $ a) ;. Y a partir de PHP 5.4.0, se eliminó el paso por referencia del tiempo de llamada, por lo que su uso generará un error fatal.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow