【问题标题】:PHP 5 passing class Object as parameter, is it always a pointer or a copy or a clone?PHP 5 将类 Object 作为参数传递,它总是一个指针、一个副本还是一个克隆?
【发布时间】:2013-12-29 21:22:42
【问题描述】:

我有一个关于将对象作为参数传递的问题。当我们传递一个变量时,它会创建一个副本,但看起来 object 始终是一个引用指针,这是正确的吗?我已经使用以下示例代码进行了测试:

class Base 
{
    private $var;
    function set ($var)
    {
        $this->var = $var;
    }

    function show ()
    {
        echo $this->var, '<br>';
    }
}

class Car
{
    private $obj;
    function __construct($obj)
    {
        $this->obj = $obj;
    }

    function set ($var)
    {
        $this->obj->set($var);
    }

    function show()
    {
        $this->obj->show();
    }
}

class Bus
{
    private $obj;
    function __construct($obj)
    {
        $this->obj = $obj;
    }

    function set ($var)
    {
        $this->obj->set($var);
    }

    function show()
    {
        $this->obj->show();
    }
}

通过运行

$base = new Base();
$base->set('one');
$base->show();          // one

$bus = new Bus($base);
$bus->show();           // one

$car = new Car($base);
$car->set('two');
$car->show();           // two

$base->show();          // two

$bus->show();           // two

显示结果为:

one
one
two
two
two

因此,在任何地方更改基类的变量,即使它作为参数传递给函数或另一个类也会影响所有这些,这是否意味着它总是指向同一个对象作为指针?

谢谢。

【问题讨论】:

  • 对象默认通过引用传递。但实际上,php 引用并不是真正的引用,每次你传递一个对象时,php proccesor 都会创建一个相同的新对象,如果你改变一个,它就会改变另一个。

标签: php scope


【解决方案1】:

在 PHP 中,当您将对象作为参数传递时,它是引用的副本。所以:

$ob = new StdClass;
$ob->var = "Lorem";

function aa($o) {
    $o->var="Ipsum";
}
aa($ob);
echo $ob->var;

这将输出Ipsum,但如果您将其他对象分配给该 $o 引用:

function aa($o) {
    $o = new StdClass;
    $o->var="Ipsum";
}

它将输出Lorem - 因为$ob 仍然指向之前创建的对象。

顺便说一句: 如果将函数定义更改为function aa(&amp;$o)。现在它将再次输出Ipsum,因为$o 是对$ob 的引用:)

总结一下: 在 PHP 中,默认情况下参数是按值传递的——即使它们是对象! 但是!在代码$ob = new StdClass; 中,$ob 是对对象的引用。所以默认情况下,我们将传递引用的副本。它们将指向相同的对象。但是如果你改变传递的变量($o = new StdClass;),$ob 仍然指向同一个对象。这就是为什么修改后给定示例将输出Lorem

您可以使用与号 (&) 通过引用传递参数,但对于对象,它通常是无用的。

【讨论】:

  • 在不正确的 PHP 5 中,您不需要使用 & 引用传递对象。
  • @Jessica 这只是附加信息,所以答案是完整的 - 我想我已经给出了简单的例子。在大多数情况下 & 是没有意义的,但是如果由于某种原因您必须更改引用对象(例如在第二个函数中),这就是我们需要的。
  • @Andy 谢谢你的详细解释!新年快乐!
  • 执行第一个代码 sn-p 实际上是为我返回“Lorem”。
  • @MAB,感谢您指出,幸运的是代码或解释中没有错误,我只是忘记在代码片段中实际执行aa 函数。添加aa($ob); 行:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-20
  • 2018-10-22
  • 2023-01-18
  • 2018-06-12
  • 1970-01-01
  • 2012-01-20
相关资源
最近更新 更多