2012-07-19 13 views
5

Duplicar posible:
In PHP can someone explain cloning vs pointer reference?Si se pasan objetos por alias, ¿cuándo pasaría por referencia?

Según http://php.net/manual/en/language.oop5.references.php

Uno de los puntos clave de PHP 5 POO que a menudo se menciona es que "los objetos se pasan por referencias por defecto ". Esto no es del todo cierto. Esta sección rectifica ese pensamiento general usando algunos ejemplos.

Una referencia de PHP es un alias, que permite que dos variables diferentes escriban en el mismo valor. A partir de PHP 5, una variable de objeto ya no contiene el objeto como valor. Solo contiene un identificador de objeto que permite a los usuarios de acceso buscar el objeto real. Cuando un objeto se envía por argumento, se devuelve o se asigna a otra variable, las diferentes variables no son alias: contienen una copia del identificador, que apunta al mismo objeto.

Si los objetos se pasan por alias o controlador, entonces, ¿en qué situación le gustaría pasar por referencia?

myFunc($obj); // Pass by alias/handler 

myFunc(& $obj); // Pass by reference (when would you do this?) 

myFunc(clone $obj); // Create a new object 

¿Cuáles son los diferentes casos de uso para cada uno de estos?

+2

Creo que esta conferencia cubrió el tema: http://www.youtube.com/watch?v=bxxIXPc9IR8 (entre otras cosas) –

+2

Nota, el tiempo de referencia de la llamada por referencia ha quedado obsoleto desde al menos 5.3, si no antes La función declara a qué argumentos espera que se refiera, y la persona que llama no tiene que especificar que son referencias, y, de hecho, no debería. – cHao

Respuesta

2

¿Cuáles son los diferentes casos de uso para cada uno de estos?

Usted ya nombrados los tres diferentes casos de uso:

  1. pasar un objeto como parámetro
  2. Pasando un alias como parámetro
  3. Pasar un clon de objeto como parámetro

Naturalmente, usted hace cada una de estas tres cosas cuando necesita hacer el caso específico. Normalmente solo necesitas 1. en 99.9%. Haz el otro 0.1% cuando lo necesites.

Un caso de uso examlary (como se pide en los comentarios) para un alias de variable como parámetro como un pequeño ejemplo (Demo):

class VarFreezer 
{ 
    private $alias; 
    private $value; 
    public function __construct(&$object) { 
     $this->alias = &$object; 
     $this->value = $object; 
    } 
    public function restore() 
    { 
     $this->alias = $this->value; 
    } 
} 

$var = new stdClass(); 
$var->value = 'I am an object now.'; 

$freezer = new VarFreezer($var); 

$var = 'I am a string now.'; 

$freezer->restore(); 

var_dump($var); 
+0

¿Alguna idea de lo que sería un caso de uso específico para 'myFunc (& $ obj)'? –

+0

Eso está pasando específicamente un alias variable como parámetro. Entonces puede hacer referencia a la misma variable con un segundo nombre. – hakre

+0

@Dev Pregunto específicamente sobre los objetos y su comportamiento cuando pasan a funciones, no a primitivas como cadenas. –

2

Cuando das un objeto a un método de la referencia a la existente Se pasan los objetos para que tenga la variable en el ámbito de llamada y la variable de parámetro de método en el alcance del método haciendo referencia al mismo objeto.

Puede usar explícitamente & para dar una referencia a una primitiva como una matriz, de modo que un método invocado pueda cambiar los datos de la matriz original. Para los objetos, este es el valor predeterminado hoy en día como mencionaste.

Un clon parece obvio.

Con & $ obj usted crea un alias para $ obj no es una referencia al objeto $ obj se refiere a. Citando php.net:

$c = new A; 
$d = &$c; 
$c->foo = 2; 
$c = NULL; 
echo $d->foo."\n"; // Notice: Trying to get property of non-object... 
2

myfunc ($ obj) pasan // identificador de

para cuando su función necesita para obtener acceso al objeto y manipular/leer de él de alguna manera.

myfunc (& $ obj) // pase con referencia al identificador.

La clave aquí es que se pasa una referencia al identificador. Lo que significa que si la variable externa ($ obj) se establece en nulo, el objeto interno también se vuelve nulo porque eliminó el identificador de $ obj y, por lo tanto, la referencia a él también se eliminó. A diferencia de cuando ingresas el identificador porque lo que realmente haces es pasar una copia del identificador y, por lo tanto, si $ obj se estableció en nulo, el valor dentro de la función aún apunta al objeto.

ejemplo:

var x = new Object(); 

var y = x //y and x both contain **different** identifiers to the same object in memory. 

function a($_a){} // a function for examples 

a($y) // passes in a copy of $y so $_a (inside the function) is a third identifier pointing to th in memory object 

a(& $y) // now $_a contains the **same** identifier as $y so if either is emptied then the other is also emptied. 

a(clone $y) //creates a new object identical to the first and passes in an identifier of the new object. 

esa es la esperanza lo suficientemente claro.

pasaría un identificador por referencia si desea poder modificar o eliminar el identificador desde el interior de la función y hacer que afecte a la variable de identificador externo mientras puede devolver un valor calculado independientemente. Por ejemplo, serializar un objeto, guardarlo en un archivo, devolver la cadena del archivo, pero también borrar el identificador para que el objeto se borre de la memoria.

Cuestiones relacionadas