How do you pass objects by reference in PHP 5?

Brian Graham picture Brian Graham · Feb 17, 2012 · Viewed 29.3k times · Source

In PHP 5, are you required to use the & modifier to pass by reference? For example,

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

In PHP4 you needed the & modifier to maintain reference after a change had been made, but I'm confused on the topics I have read regarding PHP5's automatic use of pass-by-reference, except when explicity cloning the object.

In PHP5, is the & modifier required to pass by reference for all types of objects (variables, classes, arrays, ...)?

Answer

webbiedave picture webbiedave · Feb 17, 2012

are you required to use the & modifier to pass-by-reference?

Technically/semantically, the answer is yes, even with objects. This is because there are two ways to pass/assign an object: by reference or by identifier. When a function declaration contains an &, as in:

function func(&$obj) {}

The argument will be passed by reference, no matter what. If you declare without the &

function func($obj) {}

Everything will be passed by value, with the exception of objects and resources, which will then be passed via identifier. What's an identifier? Well, you can think of it as a reference to a reference. Take the following example:

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)
}

*/

So why doesn't $a suddenly become an integer after passing it to makezero? It's because we only overwrote the identifier. If we had passed by reference:

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

makezero($a);

var_dump($a);

/* 
output:

int(0) 

*/

Now $a is an integer. So, there is a difference between passing via identifier and passing via reference.