多变量赋值是按值还是按引用进行的?

42
$a = $b = 0;
在上面的代码中,$a$b都被赋值为0吗?还是$a只是引用了$b
7个回答

57

使用原始类型进行拷贝操作。

test.php

$a = $b = 0;

$b = 3; 

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

输出:

int(0) 
int(3)

然而对于对象来说,情况就有所不同了(PHP 5)

test.php

class Obj
{ 
    public $_name;
}

$a = $b = new Obj();

$b->_name = 'steve';

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

输出

object(Obj)#1 (1) { ["_name"]=> string(5) "steve" } 
object(Obj)#1 (1) { ["_name"]=> string(5) "steve" }

9
请注意,这个例子是误导性的:改变对象的属性并不等同于改变对象所引用的变量。因为变量从未改变,所以它当然是相同的。 - KingCrunch
1
根据文档,PHP使用写时复制系统。这意味着对于诸如字符串或整数之类的基本类型,它们在更改时实际上是在内存中创建的。这就是为什么,与我们可能想的相反,在小变量上创建引用以优化性能可能不会带来预期的效果,因为PHP需要在创建引用之前先创建它。然而,自PHP5以来,默认情况下通过引用传递对象。 - bgondy
4
使用 clone 可以将对象的引用赋值更改为复制赋值。例如: $a = clone $b = new Obj; - Will B.
在类变量声明级别上,它会是什么样子?像这样 private $_name = $address = ""; - Chaminda Bandara

20

把这段代码视为:

$a = ($b = 0);

表达式$b = 0不仅将0赋值给$b,还产生了一个结果。该结果是赋值语句的右侧部分,或者说就是$b被赋予的值。

因此,$a也被赋值为0


9
你可以自己尝试一下
$a = $b = 0;
$a = 5;
echo $b;

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

目前我并不是很在意:D

因此: 不,它们都是独立变量,值为0


在这个例子中,你不得不在第二行将5赋值给$b来证明引用不存在,是的,你是正确的。我想把这个问题放在这里也对其他人搜索有好处... - Evil Elf
@Evil:不想思考这个问题,所以也加上了另一种方式。两者都返回0,因此无论如何都是正确的 :) - KingCrunch

5
我建议你阅读一篇好文章:http://terriswallow.com/weblog/2007/multiple-and-dynamic-variable-assignment-in-php/。其中一个评论中写道:

需要注意的是,如果你在一行上使用多个赋值操作符来分配对象,那么该对象将被分配为引用。因此,如果您使用任何一个变量来更改对象的属性值,则该值实际上会在两个变量中同时更改。

所以,我个人建议您分别分配变量。
供参考:
$a = $b = 4;
var_dump($a, $b);
$b = 5;
var_dump($a, $b);

产生:

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

但是:
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);

产出:

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

因此结论是,基本类型没有参考资料,但对象有参考资料。

我们实际上通过一些测试证明了这是错误的。 - Evil Elf

4

如果你正在进行赋值操作,则该赋值会将原变量复制到新变量中。

示例1:

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

上述代码会返回 0,因为它是按值分配的。 示例2:
$a = ($b = 4) + 5; // $a is equal to 9 now, and $b has been set to 4.

在PHP中,通常采用按值分配的方式进行赋值。但是,对于对象,PHP 5会自动采用按引用分配的方式进行赋值。使用clone关键字可以显式地复制对象。 示例3
$a = $b = $c = new DOMdocument();
$c->appendChild($c->createElement('html'));
echo $a->saveHTML();

上述代码将打印出<html></html>

2

1

它将它们都赋值为0


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接