q.Then
q.Then

Reputation: 2753

Why does PHP assignment behave this way?

I thought PHP = was a simple value assignment. For example:

$x = 1;
$a = $x;
$b = $x;
$a++;
echo $a;
echo $b;

Produces 21 as expected. However, the below code behaves different then what I expected. I was basically trying to assign the "same" value to many variables:

class X {
    public $val = 0;

    public function doSomething() {
      $this->val = "hi";
    }
}

function someFunction() {
    $template = array('non_object' => 0, 'object' => new X());
    $a = $template;
    $b = $template;

    //Do something
    $a['object']->doSomething();

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

Produces:

array(2) {
  ["non_object"]=>
  int(0)
  ["object"]=>
  object(X)#1 (1) {
    ["val"]=>
    string(2) "hi"
  }
}
array(2) {
  ["non_object"]=>
  int(0)
  ["object"]=>
  object(X)#1 (1) {
    ["val"]=>
    string(2) "hi"
  }
}

As you can see the object property in array A changed as expected, but also changed in array B.

You can check the code here: http://sandbox.onlinephpfunctions.com/code/bff611fc9854b777114d38a3b4c60d524fdf2e19

How can I assign the same value to many PHP variables and manipulate them without having them in this "quantum entanglement" state and without copying?

Upvotes: 6

Views: 173

Answers (3)

Abhinav
Abhinav

Reputation: 8168

As of PHP 5, all objects are passed and assigned by reference

Take your code below

  $a = $template;
  $b = $template;

Reason why you got the unexpected result:

What exactly happens here is , $a and $b are just like 'pointers' or 'handlers' pointing to that same object $template and thats the reason you met something unexpected cos you changed the object through the one of the references $a and since $b also references the same object, you noticed the change

From PHP Manual Objects and References

One of the key-points of PHP5 OOP that is often mentioned is that "objects are passed by references by default". This is not completely true. This section rectifies that general thought using some examples.

A PHP reference is an alias, which allows two different variables to write to the same value. As of PHP5, an object variable doesn't contain the object itself as value anymore. It only contains an object identifier which allows object accessors to find the actual object. When an object is sent by argument, returned or assigned to another variable, the different variables are not aliases: they hold a copy of the identifier, which points to the same object.

Upvotes: 1

Chen Sturmweizen
Chen Sturmweizen

Reputation: 639

If you want to assign value only, u can use function: clone

class X {
    public $val = 0;

    public function increment() {
    $this->val += 1;
    }
}

function someFunction() {
    $template =new X();
    $a = $template;
    $b = clone $template;

    //Increment a
    $a->increment();

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

someFunction();

$x = 1;
$a = $x;
$b = $x;

$a++;
echo $a;
echo $b;

check this

Upvotes: 1

Ijas Ahamed N
Ijas Ahamed N

Reputation: 6110

You have assigned variable $a and $b with same object. So if you call $a["object"]->doSomething() or $b["object"]->doSomething() will give same result because $a["object"] and $b["object"] are same.

If you need outputs to be different, try below code:

class X {
    public $val = 0;

    public function doSomething() {
      $this->val = "hi";
    }
}

function someFunction() {
    $a = array('non_object' => 0, 'object' => new X());
    $b = array('non_object' => 0, 'object' => new X());

    //Do something
    $a['object']->doSomething();

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

Output will be as below :

array(2) {
  ["non_object"]=>
  int(0)
  ["object"]=>
  object(X)#1 (1) {
    ["val"]=>
    string(2) "hi"
  }
}
array(2) {
  ["non_object"]=>
  int(0)
  ["object"]=>
  object(X)#2 (1) {
    ["val"]=>
    int(0)
  }
}

Here you are assigning different object to $a an $b.

Please check this

Upvotes: 4

Related Questions