¿Cómo pasas objetos por referencia en PHP 5?

En PHP 5, ¿estás obligado a usar el modificador & para pasar por referencia? Por ejemplo,

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

En PHP4 necesitabas el modificador para mantener la referencia después de realizar un cambio, pero estoy confundido con los temas que he leído sobre el uso automático de PHP5 de pass-by-reference, excepto cuando explícitamente se clona el objeto.

En PHP5, ¿se requiere el modificador & para pasar por referencia para todos los tipos de objetos (variables, clases, matrices, …)?

¿Estás obligado a usar el modificador & para pasar por referencia?

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

 function func(&$obj) {} 

El argumento se aprobará por referencia, sin importar qué. Si declaras sin el &

 function func($obj) {} 

Todo se pasará por valor, con la excepción de los objetos y recursos, que luego se pasarán a través de un identificador . ¿Qué es un identificador? Bueno, puedes pensar que es una referencia a una referencia. Toma 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é $a repente no se convierte en un número 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 número entero. Entonces, hay una diferencia entre pasar por identificador y pasar por referencia .

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 tienes allí (primero necesitas $ 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. 

Lo estás usando mal El signo $ es obligatorio para cualquier variable. Debería 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 en dos objetos es un intercambio 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);