Are multiple variable assignments done by value or reference?
Asked Answered
F

8

43
$a = $b = 0;

In the above code, are both $a and $b assigned the value of 0, or is $a just referencing $b?

Fail answered 6/6, 2011 at 19:42 Comment(0)
D
57

With raw types this is a copy.

test.php

$a = $b = 0;

$b = 3; 

var_dump($a);
var_dump($b);

Output:

int(0) 
int(3)

With objects though, that is another story (PHP 5)

test.php

class Obj
{ 
    public $_name;
}

$a = $b = new Obj();

$b->_name = 'steve';

var_dump($a);
var_dump($b);

Output

object(Obj)#1 (1) { ["_name"]=> string(5) "steve" } 
object(Obj)#1 (1) { ["_name"]=> string(5) "steve" }
Disadvantage answered 6/6, 2011 at 19:47 Comment(4)
Note, that the example is misleading: Changing the property of an object is not the same as changing the variable the object is referenced from. Because the variable never changed, it is of course the same.Chastise
According to documentation, PHP uses a copy on write system. It means that with primitive types such as strings or ints are really created in memory on change. That's why, contrary to what we might think, creating references to optimize performance on small variables may not bring the desired effect, because PHP needs to create it before. However, objects are passed by reference by default since PHP5.Horny
The assign by reference with objects can be changed to assign by copy using clone. EG: $a = clone $b = new Obj;Universe
At the class variable declaration level how it would be ? Like this private $_name = $address = "";Certainly
T
19

Regard this code as:

$a = ($b = 0);

The expression $b = 0 not only assigns 0 to $b, but it yields a result as well. That result is the right part of the assignment, or simply the value that $b got assigned to.

So, $a gets assigned 0 as well.

Tann answered 6/6, 2011 at 19:46 Comment(0)
C
9

You could have tried it yourself

$a = $b = 0;
$a = 5;
echo $b;

or

$a = $b = 0;
$b = 5;
echo $a;

(currently I dont really care :D)

Thus: No, they are both independent variables with the value 0.

Chastise answered 6/6, 2011 at 19:45 Comment(2)
In that example, wouldn't you have to assign 5 to $b on the second line to prove the reference was not present? and yes, you are correct. I figured having the question up here would be nice for others searching as well though...Fail
@Evil: Don't want to think about it, so added the other way round too. Both return 0, thus it must be true in any case :)Chastise
A
5

I'll recommend a good read on this: http://terriswallow.com/weblog/2007/multiple-and-dynamic-variable-assignment-in-php/ . In one of comments, you can read:

It should be noted that if you use multiple assignment on one line to assign an object, the object is assigned by reference. Therefore, if you change the value of the object’s property using either variable, the value essentially changes in both.

So I'll personally recommend that you assign the variables separately.

For the record:

$a = $b = 4;
var_dump($a, $b);
$b = 5;
var_dump($a, $b);

Yields:

int(4)
int(4)
int(4)
int(5)

But:

class Tmp
    {
    public $foo;

    public function __construct()
        {
        $this->foo = 'bar';
        }
    }

$a = $b = new Tmp();
var_dump($a, $b);
$a->foo = 'oth';
var_dump($a, $b);

Yields:

object(Tmp)#1 (1) {
  ["foo"]=>
  string(3) "bar"
}
object(Tmp)#1 (1) {
  ["foo"]=>
  string(3) "bar"
}
object(Tmp)#1 (1) {
  ["foo"]=>
  string(3) "oth"
}
object(Tmp)#1 (1) {
  ["foo"]=>
  string(3) "oth"
}

So the conclusion is that there is no reference for primitives, but there IS a reference to objects.

Amii answered 6/6, 2011 at 19:47 Comment(1)
we proved this false actually with some tests.Fail
L
4

It depends what're you assigning.

If you're assigning a value, then the assignment copies the original variable to the new one.

Example 1:

$a = $b = 0;
$b++; echo $a;

Above code will return 0 as it's assignment by value.

Example 2:

$a = ($b = 4) + 5; // $a is equal to 9 now, and $b has been set to 4.

An exception to the usual assignment by value behaviour within PHP occurs with objects, which are assigned by reference in PHP 5 automatically. Objects may be explicitly copied via the clone keyword.

Example 3

$a = $b = $c = new DOMdocument();
$c->appendChild($c->createElement('html'));
echo $a->saveHTML();

Above code will print <html></html>.

Leekgreen answered 21/2, 2015 at 18:5 Comment(0)
W
2

Both $a and $b are assigned that value of 0. If you wanted $a to reference $b, you would preempt it with an ampersand, e.g.:

$a = & $b = 0;

http://php.net/manual/en/language.oop5.basic.php

Woll answered 6/6, 2011 at 19:48 Comment(0)
N
1

its assigns them both the value of 0

Nacreous answered 6/6, 2011 at 19:46 Comment(0)
C
0

Values

$a = $b = 0;

is the same as

$a = 0;
$b = 0;

Objects

$obj = new TestObject();
$a = $b = $obj;

is the same as

$obj = new TestObject();
$a = $obj;
$b = $obj;

Setting a variable equal to an existing object in PHP will pass by REFERENCE. It will not do a deep copy unless you add the clone keyword.

Long chains

This pattern applies to longer chains too.

$a = $b = $c = 0;

is the same as

$a = 0;
$b = 0;
$c = 0;

You can confirm using a PHP sandbox: https://onlinephp.io/c/7b70f

Cimino answered 8/4 at 19:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.