Pregunta

Recibo señales contradictorias por todas partes.

¿Utilizo el signo comercial para pasar variables por referencia o no?

El siguiente enlace parece decirme que está en desuso y que ya no es necesario:
http://gtk.php.net/manual/en/html/tutorials/tutorials.changes.references.html

Pero hilos como este me hacen dudar:
¿El paso por referencia del tiempo de llamada está en desuso?
PHP y signo comercial

Permítanme formular mi pregunta como ejemplo.

Si hago una función, usando PHP 5.5.5:

function recurring_mailer_form($form, $form_state) 
{

}

¿Es lo mismo que:

function recurring_mailer_form($form, &$form_state) 
{

}

?

¿Fue útil?

Solución

La razón por la que diferentes artículos parecen decir cosas diferentes es que hablan de diferentes tipos de paso por referencia.

Lo principal que determina si un parámetro debe pasarse por referencia es la firma de la función en sí, y los fundamentos de esto no han cambiado desde PHP 4.Considere este ejemplo:

function foo( $by_value, &$by_reference ) { /* ... */ }

$a = 1; $b = 2;
foo( $a, $b );

Aquí, la variable exterior $a se pasa a la función por valor, como si se asignara como $by_value = $a; - cambios a $by_value no puede afectar $a.La variable $b sin embargo se está pasando por referencia;como una asignación de la forma $by_reference =& $b; esto significa que hay una variable a la que hacen referencia dos nombres, y cualquier asignación a una actuará como una asignación a ambas.

Si pasa un valor "ordinario" (una cadena, número o matriz) por valor, su valor simplemente se copia en la nueva variable. A partir de PHP 5:Sin embargo, si pasa un objeto por valor, sucede algo ligeramente diferente: el "valor" copiado es solo un puntero al mismo objeto.Esto significa que si $a Si fueras un objeto, podrías llamarlo $by_value->some_property = 42; y $a->some_property también sería 42.Sin embargo, si asigna algún valor nuevo a $by_value, todavía no afectaría $a.

Hasta PHP 5.4, había un extra forma de pasar un parámetro por referencia, que era "forzar" el comportamiento de referencia en el momento de la llamada.Esto significaba que podías escribir foo(&$a, &$b); y "capturar" los cambios realizados en $by_value dentro de foo() función.Confiar en esto era generalmente una mala idea, por lo que se eliminó.(Aterrizó en 5.4 porque estaba previsto que se eliminara en PHP 6, pero ese proyecto quedó en suspenso indefinidamente, y los cambios más pequeños llegaron a 5.3 y 5.4).

Finalmente, las funciones pueden devolver una variable por referencia (como discutido en el manual aquí).Esto es un poco complicado, ya que en realidad requiere que pongas & en dos lugares:al comienzo de la declaración de función, para decir que return debería significar "devolver esta referencia de variable", no "devolver este valor";y en el código que lo llama, asignar una variable a esa referencia, en lugar de simplemente copiar su valor.Aquí hay un ejemplo tonto que combina un parámetro de referencia con un retorno de referencia (los dos no tienen que ir juntos, es solo un ejemplo):

function &bar(&$some_param) { return $some_param; }
$a = 1;
$b =& bar($a);
// $b and $a now point at the same variable, not just the same value
// it was passed into and out of a function, and assigned to a new variable, 
// but all those operations were by reference

Tenga en cuenta que muchas personas creen erróneamente que pasar una variable por referencia les dará un beneficio de rendimiento y, a menudo, esta fue la única razón para utilizar el paso por referencia del tiempo de llamada.De hecho, esto suele ser incorrecto, ya que el motor Zend que impulsa PHP utiliza una técnica llamada "copiar al escribir" para dejar múltiples variables que tienen el mismo valor apuntando al mismo fragmento de memoria, incluso si no están vinculadas como referencias.De hecho, la asignación de referencias generalmente derrotas esta optimización, debido a la forma en que el motor rastrea qué variables están en el estado de copia en escritura.

Otros consejos

No, no es.

  • Los objetos siempre se pasan automáticamente como referencias (¡Información! ¡Vea a continuación para obtener información importante adicional!)

  • Declarar los parámetros como referencias deben ocurrir en la definición de función:

    function test(&$var) {}
    

    No En el momento de llamarlo:

    // wrong
    $var = '123';
    test(&$var);
    


Si pasa un objeto como de costumbre, puede alterar el estado del objeto (propiedades).
Asumir que $obj es una instancia de la clase TestClass que contiene una variable miembro llamada hello (Haga clic aquí para obtener una muestra completa en ideone.com):

function modify($obj) { $obj->hello = 'world (modified)!'; }

$obj->hello = 'world';
modify($obj);
var_dump($obj->hello);  // outputs "world (modified!)"

Esto debería explicarse por sí mismo. Ahora, usando el mismo código pero asignando otro valor a $obj en su lugar, modificar el estado del objeto no tiene modificación (→ ideone.com):

function modify($obj) { $obj = 42; }
// ...
var_dump($obj->hello);  // outputs "world"

Solo aceptar el parámetro explícitamente como referencia nos da la capacidad de cambiar completamente el contenido de la variable (→ ideone.com):

function modify(&$obj) { $obj = 42; }
// ...
var_dump($obj);         // outputs "42"

No, esos no son lo mismo. PHP 5.4+ simplemente detecta a la llamada si se necesita referencia cuando se llama a la función verificando la declaración.

Entonces, no, no está en desuso ya que necesita el operador de referencia en la declaración de función si ese es su uso previsto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top