-1

在我的__clone方法中,我通过引用将一个变量分配给另一个变量。在克隆之后,我期望发生的是,当我为一个对象更改此变量时,它会在另一个对象中更改。但这似乎没有发生。

我的代码:

class a {
    var $a;

    function a($var = NULL) {
        if (isset($var)) {
            $this->a = $var;
        }
    }

    function __clone() {
        $temp = new a();
        $temp->a = &$this->a;
        return $temp;
    }
}

$a = new a('test');
$b = clone $a;
$b->a = 'zzz';

echo $a->a;
echo "\r\n";
echo $b->a;

输出是这样的:

test
zzz

我希望它是这样的:

zzz
zzz
4

3 回答 3

1

如果我在克隆引用被删除时没有弄错(我认为这是一种内部机制),那么您想要实现的目标会令人困惑,因为您可以简单地执行以下操作:

$a = new a('test');
$b = $a;
$b->a = 'zzz';

echo $a->a;
echo "\r\n";
echo $b->a;

引用:“...您想创建另一个对象的新实例,以便副本拥有自己的单独副本。”

来源: http: //php.net/manual/ro/language.oop5.cloning.php

于 2013-10-26T17:16:12.503 回答
1

那是因为__clone()忽略了返回值。您可以看到,如果您将$temp->a = &$this->a;line 更改为$temp->a = 'CLONED';然后简单地echo $b->a;

所以你不能改变克隆的结果对象。

于 2013-10-26T17:17:35.573 回答
1

在调用您的__clone方法之前,PHP 已经按值复制了所有属性。PHP 完成克隆对象后,将调用您的方法。因此,您在该方法中访问的任何属性都已经是值副本。该文档指出:

当一个对象被克隆时,PHP 5 将对该对象的所有属性执行一个浅拷贝。任何引用其他变量的属性都将保持引用。

克隆完成后,如果定义了 __clone() 方法,则将调用新创建的对象的 __clone() 方法,以允许任何需要更改的必要属性。

您可以在本页的第二段中找到它。

虽然这不是一个非常漂亮的解决方法,但您可以重命名您的__clone方法。然后,您可以使用该方法克隆您的对象,尽管这当然不再是实际的克隆,因为它不使用该接口进行克隆。

于 2013-10-26T17:21:10.057 回答