为什么PHP赋值行为如此?

时间:2016-01-06 05:47:52

标签: php

我认为PHP =是一个简单的值赋值。例如:

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

按预期生成21。但是,以下代码的行为与我的预期不同。我基本上试图将“相同”值分配给许多变量:

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

产地:

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

正如您所见,object中的array A属性已按预期更改,但array B也已更改。

您可以在此处查看代码:http://sandbox.onlinephpfunctions.com/code/bff611fc9854b777114d38a3b4c60d524fdf2e19

如何为许多PHP变量分配相同的值并操纵它们而不使它们处于这种“量子纠缠”状态而不进行复制?

3 个答案:

答案 0 :(得分:5)

您已为同一个对象分配变量$ a和$ b。因此,如果您致电$a["object"]->doSomething()$b["object"]->doSomething()会得到相同的结果,因为$a["object"]$b["object"]相同。

如果您需要输出不同,请尝试以下代码:

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

输出如下:

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

在这里,您将不同的对象分配给$ a和$ b。

Please check this

答案 1 :(得分:1)

如果您只想分配值,可以使用函数: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

答案 2 :(得分:1)

从PHP 5开始,所有对象都通过引用传递和分配

使用下面的代码

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

您获得意外结果的原因:

这里到底发生了什么,$a$b就像'指针'或'处理程序'指向同一个对象$template,这就是你遇到意想不到的事情的原因通过其中一个引用$a更改了对象,并且由于$b也引用了同一个对象,您注意到了更改

来自PHP手册 Objects and References

  

经常提到的PHP5 OOP的一个关键点是   “默认情况下,对象通过引用传递”。这不完全   真正。本节使用一些例子来纠正这种普遍的想法。

     

PHP引用是一个别名,它允许两个不同的变量   写入相同的值。从PHP5开始,对象变量不会   将对象本身包含为值。它只包含一个对象   标识符,允许对象访问者查找实际对象。   当一个对象通过参数发送,返回或分配给另一个对象时   变量,不同的变量不是别名:它们持有副本   标识符,指向同一个对象。