2012-02-17 11 views
19

En PHP 5, ¿está obligado a utilizar el modificador & para pasar por referencia? Por ejemplo,¿Cómo pasas objetos por referencia en PHP 5?

class People() { } 
$p = new People(); 
function one($a) { $a = null; } 
function two(&$a) { $a = null;) 

En PHP4 que necesita el modificador & para mantener la referencia después se había hecho un cambio, pero estoy confundido sobre los temas que he leído en relación con el uso automático de PHP5 de pasar por referencia, excepto cuando explícitamente clona el objeto.

En PHP5, es el modificador&requerido para pasar por referencia para todos los tipos de objetos (variables, clases matrices, ...)?

+3

El manual resolverá todos sus problemas. http://php.net/manual/en/language.oop5.references.php – rdlowrey

Respuesta

76

que están obligados a utilizar el modificador & pasar por referencia?

Técnicamente/semánticamente, la respuesta es sí , incluso con objetos. Esto se debe a que hay dos maneras de pasar/asignar un objeto: por referencia o por identificador. Cuando una declaración de función contiene un &, como en:

function func(&$obj) {} 

El argumento se pasa por referencia, no importa qué. Si se declara sin el Todo &

function func($obj) {} 

se pasa por valor, con la excepción de los objetos y recursos, que luego se pasó a través de identificador. ¿Qué es un identificador? Bueno, puedes pensar que es una referencia a una referencia. Tomemos el siguiente ejemplo:

class A 
{ 
    public $v = 1; 
} 

function change($obj) 
{ 
    $obj->v = 2; 
} 

function makezero($obj) 
{ 
    $obj = 0; 
} 

$a = new A(); 

change($a); 

var_dump($a); 

/* 
output: 

object(A)#1 (1) { 
    ["v"]=> 
    int(2) 
} 

*/ 

makezero($a); 

var_dump($a); 

/* 
output (same as before): 

object(A)#1 (1) { 
    ["v"]=> 
    int(2) 
} 

*/ 

Entonces, ¿por qué no $a convertido de repente en un entero después de pasarlo a makezero? Es porque solo sobrescribimos el identificador .Si hubiéramos pasado por referencia :

function makezero(&$obj) 
{ 
    $obj = 0; 
} 

makezero($a); 

var_dump($a); 

/* 
output: 

int(0) 

*/ 

Ahora $a es un entero. Entonces, hay una diferencia entre pasar a través del identificador y pasar por referencia.

+11

Gracias por explicar la diferencia entre los identificadores y las referencias, el manual no fue muy claro al respecto. –

+6

explicación muy útil y clara! – skyfree

+0

Así es como los objetos javascript se pasan por defecto también. –

0

Lo está utilizando mal. El signo $ es obligatorio para cualquier variable. Debe ser: http://php.net/manual/en/language.references.pass.php

function foo(&$a) 
{ 
$a=null; 
} 


foo($a); 
To return a reference, use 

function &bar($a){ 
$a=5; 
return $a 

} 

En objetos y matrices, una referencia al objeto se copia como el parámetro formal, cualquier operación de igualdad de dos objetos es un cambio de referencia.

$a=new People(); 
$b=$a;//equivalent to &$b=&$a roughly. That is the address of $b is the same as that of $a 

function goo($obj){ 
//$obj=$e(below) which essentially passes a reference of $e to $obj. For a basic datatype such as string, integer, bool, this would copy the value, but since equality between objects is anyways by references, this results in $obj as a reference to $e 
} 
$e=new People(); 
goo($e); 
+0

Olvidé el signo '$', lo siento. –

+0

y olvidé leer la pregunta, lo siento. Ver mi edición –

0

Los objetos pasarán por referencia. Los tipos incorporados serán pasados ​​por valor (copiados);

Lo que sucede detrás de escena es que cuando pasas una variable que contiene un objeto, es una referencia al objeto. Entonces, la variable misma se copia, pero aún hace referencia al mismo objeto. Entonces, esencialmente hay dos variables, pero ambas apuntan al mismo objeto. Los cambios realizados a los objetos dentro de una función persistirán.

En el caso del código que usted tiene allí (Lo primero que necesita $ incluso con &):

$original = new Object(); 

one($original); //$original unaffected 
two($original); //$original will now be null 

function one($a) { $a = null; } //This one has no impact on your original variable, it will still point to the object 

function two(&$a) { $a = null;) //This one will set your original variable to null, you'll lose the reference to the object. 
+0

Entonces, ¿enteros, cadenas, caracteres y booleanos pasan por valor, a menos que se use el modificador 'y'? –

+0

@BrianGraham sí. Si está familiarizado con los punteros en C/C++ $ original en el ejemplo anterior es algo así. Tiene una dirección para el objeto que creamos. $ original se copia cuando pasa a la función uno ($ a), pero como contiene una dirección, la copia apunta al mismo objeto. – Chris

+0

Usted dice que en PHP5 los objetos se pasan por referencia, ¿verdad? Entonces, ¿por qué estás usando el modificador 'y' para probar tu punto si no es necesario, no me ayuda a entender mi pregunta. –

Cuestiones relacionadas