在PHP中,对象是按值还是按引用分配的?

34

在这段代码中:

<?php
class Foo
{
    var $value;

    function foo($value)
    {
        $this->setValue($value);
    }

    function setValue($value)
    {
        $this->value=$value;
    }
}

class Bar
{
    var $foos=array();

    function Bar()
    {
        for ($x=1; $x<=10; $x++)
        {
            $this->foos[$x]=new Foo("Foo # $x");
        }
    }

    function getFoo($index)
    {
        return $this->foos[$index];
    }

    function test()
    {
        $testFoo=$this->getFoo(5);
        $testFoo->setValue("My value has now changed");
    }
}
?>

当运行Bar::test()方法并更改foo对象数组中的第5个值时,实际上数组中的foo # 5会受到影响吗?还是$testFoo变量仅是一个局部变量,在函数结束时就会被销毁?


1
相关问题:https://dev59.com/ZnVD5IYBdhLWcg3wXaid。 - TSomKes
3个回答

44
为什么不运行这个函数,找出答案呢?
$b = new Bar;
echo $b->getFoo(5)->value;
$b->test();
echo $b->getFoo(5)->value;

对我来说,上面的代码(连同你的代码)产生了以下输出:
Foo #5
My value has now changed

这不是因为“按引用传递”,而是因为“按引用赋值”。在PHP 5中,对象的默认行为是按引用赋值。如果你想要按值赋值,可以使用clone关键字。

这在 PHP 4 上会发生什么? - Ali
PHP 4能否像PHP 5一样配置以引用方式进行赋值? - Ali
1
是的,您可以使用'=&'赋值运算符来实现,而不是'='。阅读此内容:http://ca2.php.net/manual/en/language.references.whatdo.php - Paige Ruten
1
在PHP中,对象不是通过引用分配的,而是一个代表内存中对象的值(标识符)。即使该值被复制,它很小,PHP内部始终使用由标识符表示的对象。因此,对象本身没有被复制,只有它的标识符;)由于引用的使用通常是不鼓励的(因为您需要非常了解语言才能使用它们),所以只需传递而不带引用。 - hakre

31
你可以参考https://www.php.net/manual/zh/language.oop5.references.php来获取你问题的实际答案。
PHP5面向对象编程中经常提到的一个关键点是“对象默认通过引用传递”。这并不完全正确。
PHP引用是一个别名,它允许两个不同的变量写入同一个值。从PHP5开始,对象变量不再包含对象本身作为值。它只包含一个对象标识符,该标识符允许对象访问器找到实际的对象。当对象作为参数传递、返回或分配给另一个变量时,这些不同的变量并不是别名:它们保存的是标识符的副本,该标识符指向同一个对象。

11

在PHP 4中,变量是按值传递的;而在PHP 5中,则是按引用传递的。如果要在PHP 4中按引用传递对象,你必须显式地标明:


$obj = &new MyObj;

1
在PHP4中,当您按值传递时,它是一个隐式克隆吗? - lud

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