2011-09-17 15 views
19

Intenté googlear, intenté la documentación de PHP, busqué SO para obtener una respuesta pero no encontré nada satisfactorio. Estaba leyendo un libro en el que el autor utilizó Return by Reference pero nunca explicó de qué se trataba. el código usado por el autor esDevolver por referencia en PHP

function &getSchool() { 
    return $this->school; 
} 

¿Alguien puede explicar en palabras simples con un ejemplo sobre este concepto.

gracias.

+1

Los documentos [PHP] (http://php.net/manual/en/language.references.return.php) es la respuesta definitiva a esto - asegúrese de examinar toda la sección de "explicaciones explicadas". – Jon

+3

Cmon Jon, he dicho que ya he pasado por la documentación, y para admitir que no lo entendí bastante bien desde allí. esa es la razón por la que estoy preguntando aquí, agradecería si tiene alguna de su versión para explicar :) –

+0

El enlace proporcionado por Jon lo explica bien con el ejemplo. – xdazz

Respuesta

28

Suponga que tiene esta clase:

class Fruit { 
    private $color = "red"; 

    public function getColor() { 
     return $this->color; 
    } 

    public function &getColorByRef() { 
     return $this->color; 
    } 
} 

La clase tiene una propiedad privada y dos métodos que permiten acceder a él. Uno regresa por valor (comportamiento predeterminado) y el otro por referencia. La diferencia entre los dos es que:

  • Cuando se utiliza el primer método, puede realizar cambios en el valor devuelto y esos cambios no se reflejarán en el interior de la propiedad privada de Fruit porque en realidad está modificando una copia de la valor de la propiedad.
  • Cuando se utiliza el segundo método, que son de hecho volver un alias para Fruit::$color - un nombre diferente el cual se refiere a la misma variable . Por lo tanto, si hace algo con eso (incluida la modificación de su contenido), en realidad está realizando directamente la misma acción sobre el valor de la propiedad.

Aquí hay un código para probarlo:

echo "\nTEST RUN 1:\n\n"; 
$fruit = new Fruit; 
$color = $fruit->getColor(); 
echo "Fruit's color is $color\n"; 
$color = "green"; // does nothing, but bear with me 
$color = $fruit->getColor(); 
echo "Fruit's color is $color\n"; 

echo "\nTEST RUN 2:\n\n"; 
$fruit = new Fruit; 
$color = &$fruit->getColorByRef(); // also need to put & here 
echo "Fruit's color is $color\n"; 
$color = "green"; // now this changes the actual property of $fruit 
$color = $fruit->getColor(); 
echo "Fruit's color is $color\n"; 

See it in action.

Advertencia: me siento obligado a mencionar que las referencias, mientras que sí tienen usos legítimos, son una de las características que debe ser utilizado sólo en raras ocasiones y sólo si usted ha considerado cuidadosamente las alternativas primeros. Los programadores menos experimentados tienden a abusar de las referencias porque ven que pueden ayudarlos a resolver un problema en particular sin, al mismo tiempo, ver las desventajas de usar referencias (como característica avanzada, sus matices están lejos de ser obvios).

+0

Lo has explicado muy bien Jon, gracias :). –

+0

Por otro lado, todo eso está efectivamente en los documentos, pero ¿qué sucede cuando el extremo receptor no menciona el signo comercial y cómo se puede desactivar la copia por valor en una clase? P.ej. para una clase singleton. Porque no tiene mucho sentido saber que quiere devolver un valor si tiene que contar con que la persona que llama se porta bien, ¿verdad? – nus

3

El ejemplo que ha publicado es probablemente de PHP4 o anterior. Ya no es necesario devolver objetos por referencia, ya que casi siempre se hacen de esa manera automáticamente en PHP5 +.

La devolución por referencia es útil cuando desea utilizar una función para encontrar a qué variable debe vincularse una referencia. No use devolución por referencia para aumentar el rendimiento. El motor automáticamente optimiza esto por sí mismo. Solo referencias de devolución cuando tiene una razón técnica válida para hacerlo.

Ver return references in PHP docs

+0

Ya he indicado que ya he pasado por la documentación, y eso no me explica nada. quiero saber mas sobre eso –

+0

¿Has leído todos los http://www.php.net/manual/en/language.references.php? – six8

+3

Hay algunos casos en los que el retorno por referencia podría ser bueno, pero soy un oponente fuerte. Ver también mi blog: http://schlueters.de/blog/archives/125-Do-not-use-PHP-references.html – johannes

14

Fácil regla: si pasa & delante de un nombre de función en PHP puede utilizar & cuando se llama a la función (. Es decir, su valor de retorno) como si fuera una variable y no una función.

Eso es todo.


Es más fácil pensar en él como "PHP que le permite hacer referencia al valor de retorno" en lugar de PHP retorno por referencia. Como se mencionó anteriormente, simplemente coloque un & para decirle a PHP que quiere esto, si no lo coloca y trata de hacerlo a $var =& somefunction() obtendrá el error "Las variables solo se deben asignar por referencia".

Para aclarar un poco la confusión con la respuesta de Jon. En realidad, no es necesario tener dos funciones separadas, una que retorna por referencia y otra que retorna por valor; fuera de alguna convención de proyecto. El & solo le permite devolver por referencia, no lo hace forzarlo para devolverlo por referencia.

por ejemplo. misma función utilizada tanto para las asignaciones de referencia y no son de referencia

\header('content-type: text/plain'); 

class Demo 
{ 
    protected $example = 'original value'; 

    function & example() 
    { 
     return $this->example; 
    } 
} 

$demo = new Demo; 

#1 - pass by value 

$var1 = $demo->example(); 
$var1 = 'var1 value'; 

echo '$demo->example() => '.$demo->example().PHP_EOL; 
echo PHP_EOL; 

#2 - pass by reference 

$var2 =& $demo->example(); 
$var2 = 'var2 value'; 

echo '$demo->example() => '.$demo->example().PHP_EOL; 
echo '$var1 => '.$var1.PHP_EOL; 
echo '$var2 => '.$var2.PHP_EOL; 
echo PHP_EOL; 

#3 - altering other references 

$var3 =& $demo->example(); 
$var3 = 'var3 value'; 

echo '$demo->example() => '.$demo->example().PHP_EOL; 
echo '$var1 => '.$var1.PHP_EOL; 
echo '$var2 => '.$var2.PHP_EOL; 
echo '$var3 => '.$var3.PHP_EOL; 
echo PHP_EOL; 

exit; 

salida

$demo->example() => original value 

$demo->example() => var2 value 
$var1 => var1 value 
$var2 => var2 value 

$demo->example() => var3 value 
$var1 => var1 value 
$var2 => var3 value 
$var3 => var3 value 

Las referencias son grandes sin embargo, si usted no está familiarizado con ellos por favor, siga las siguientes reglas:

  • solo considere usar referencias si está tratando con una matriz grande o estructuras de datos no objeto similares
  • Nunca haga referencia a un objeto (si puede evitarlo)
  • solo permiten que una función pase por referencia si el valor se mantiene en una propiedad estática o atributo en el objeto (es decir. no es una variable temporal dentro de la función)

Las excepciones obviamente serían usos muy utilitarios (es decir, cuando realmente desea compartir un valor para simplificar el código para manipularlo).

Una vez más, NUNCA hacer referencia a objetos (que no tiene sentido!)

Cuestiones relacionadas