PHP链接方法和CLONE

时间:2014-03-20 03:51:06

标签: php chaining method-chaining

我很好奇。

一位受人尊敬的开发人员建议使用" return clone $ this"而不是简单地使用"返回$ this"他最终离开了开源项目一段时间,从未回答过我的"为什么?"问题所以我很好奇是否有任何好处。

因此,作为普通可链式方法的一个例子,我们可能会有这样的事情:

function setProperty($arg) {
    this->property = $arg;
    return $this;
 }

他的榜样更像是这样:

function setProperty($arg) {
     this->property = $arg;
     return clone $this;
}

我的印象是他错了,因为它只会在每一步都无法访问该对象的副本。

所以,如果我们使用他的方法并说出类似的东西......

class foo {
     public $value;
     function setA($arg) {
        $this->value = $arg;
        return clone $this;
     }

     function setB($arg) {
         $this->value = $arg;
         return clone $this;
     }

     function setB($arg) {
         $this->value = $arg;
         return clone $this;
     }

     function print() {
         print $this->value;
     }
}

我们有这样的一行($ obj是类foo的一个实例):

$obj->setA('a')->setB('b')->setC('c')->print();

这应该最终打印c,无论是使用克隆$ this还是普通的$ this。

...然而

$obj->setA('a')->setB('b')->setC('c');
$obj->print();

应该打印一个,因为只有第一步才会改变原始对象。第二步是从第一步更改克隆对象,第三步是从第二步更改传递给它的对象。

但是,如果你去了,那就再说一遍:

$obj = $obj->setA('a')->setB('b')->setC('c');
$obj->print();

我相信这会在任何一种方法中打印c。

如果我们原先将$ value声明为静态,那么所有这些不同的变体都应该打印一个c。

如果我理解这些东西是如何工作的,我相信我是正确的,并且看到使用"返回克隆$ this"而不是"返回$ this"。或者我错过了什么,或者我在上述假设中完全错了?

谢谢!

罗德尼

1 个答案:

答案 0 :(得分:1)

我认为您不想修改当前对象的状态然后返回克隆。相反,你要克隆然后修改。例如,

class Foo {
     private $value;

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

     function printValue() {
         echo $this->value.PHP_EOL;
     }
}

这样你的对象就变成了不可变的。

使用示例:

$a = (new Foo)->setValue('a');
$b = $a->setValue('b');

$a->printValue();
$b->printValue();

这将打印

a
b

当您“修改”$a时,这种方式$b不会被搞砸。