简体   繁体   English

PHP链接方法和CLONE

[英]PHP chaining of methods and CLONE

I am curious about something. 我对某事感到好奇。

A respected developer suggested using "return clone $this" instead of simply using "return $this" and he ended up leaving the open source project for a while and never answered my "why?" 一位受人尊敬的开发人员建议使用“ return clone $ this”而不是简单地使用“ return $ this”,他最终离开了开源项目一段时间,从未回答我的“为什么?” question so I am curious if there is ANY benefit to it. 问题,所以我很好奇它是否有任何好处。

So as an example in a normal chainable method we might have something like this: 因此,以普通的可链接方法为例,我们可能会有类似以下内容:

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

His example was more like this: 他的例子更像这样:

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

My impression was that he was wrong for this because all it would do is make a copy of the object at each step that would be inaccessible. 我的印象是他错了,因为要做的就是在无法访问的每一步都复制对象。

So if we used his method and say had something like 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;
     }
}

And we had a line like this($obj is an instance of class foo): 我们有这样一行($ obj是foo类的实例):

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

This should end up printing c regardless if done with the clone $this or just plain $this. 无论使用克隆$ this还是仅使用$ this进行打印,最终都应打印c。

However... 然而...

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

should print a since only the first step would change the original object. 应该打印一个,因为只有第一步会更改原始对象。 The second step would change a cloned object from the first step and the third step would be changing the object passed to it from the second step. 第二步将更改第一步中的克隆对象,第三步将更改第二步中传递给它的对象。

but then again if you went with: 但是如果您继续使用,则再一次:

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

I would believe this would print c in either method as well. 我相信这也会在任何一种方法中打印c。

If we had declared $value as static originally then all of these different variations should print a c. 如果我们最初将$ value声明为静态,则所有这些不同的变体都应打印c。

If I understand how this stuff all works I believe I am correct and see absolutely no benefit in using "return clone $this" as opposed to "return $this". 如果我理解这些东西如何工作,我相信我是正确的,并且看到使用“ return clone $ this”相对于“ return $ this”绝对没有好处。 Or am I missing something or am I totally wrong in my above assumptions? 还是我错过了某些东西,或者我在上述假设中完全错了?

Thanks! 谢谢!

Rodney 罗德尼

I don't think you'd ever want to modify the state of the current object and then return a clone. 我认为您永远不想修改当前对象的状态然后返回一个克隆。 Instead, you'd clone then modify. 相反,您将克隆然后进行修改。 Example, 例,

class Foo {
     private $value;

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

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

In this way your object becomes immutable. 这样,您的对象就变得不可变。

Example usage: 用法示例:

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

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

This will print 这将打印

a
b

This way $a isn't messed with when you "modify" $b . 这样$a不与当你“修改”搞砸$b

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM