克隆PHP对象不起作用

时间:2016-08-06 17:59:32

标签: php clone pass-by-reference

我有同样的问题about making a copy of an object without reference in PHP,但该解决方案无效。

我想获取集合的所有元素,更改一个属性(添加几个月)并将该新元素推送到新集合中。

所以我已经使用clone来获取Invoice的全新实例,这个实例应该受到影响,但事实并非如此。

使用此代码:

while($thisInvoiceYear <= CURRENT_YEAR) {
    $clonedInvoice = clone($thisInvoice);
    $this->extendedInvoices->push($clonedInvoice);
    $toSaveInvoice = $this->extendedInvoices->last();
    $thisInvoiceYear = $this->getCurrentYear($toSaveInvoice);
    $toSaveInvoice->Schedule->StartDate = Carbon::parse($toSaveInvoice->Schedule->StartDate)->addMonths($period);
    unset($clonedInvoice);
}

$thisInvoice是Invoice集合的对象,$this->extendedInvoices是Invoice类的方法。

问题是$toSaveInvoice中完成的每个更改都会影响原始集合元素。经过3次迭代后,对于extendedInvoices的所有元素,date都是相同的,不应该是:

enter image description here

我正在使用Laravel 5.2,但我认为没有帮助来克隆集合的元素。

你知道为什么clone()无效吗?非常感谢你的帮助。

1 个答案:

答案 0 :(得分:2)

一个好主意是先阅读手册,然后再问一个问题。

来自PHP manual

  

创建具有完全复制属性的对象的副本并不总是想要的行为。需要复制构造函数的一个很好的例子是,如果你有一个表示GTK窗口的对象,并且该对象保存了这个GTK窗口的资源,当你创建一个副本时,你可能想要创建一个具有相同属性的新窗口,让新对象保存新窗口的资源。另一个例子是,如果您的对象持有对它使用的另一个对象的引用,并且当您复制父对象时,您想要创建另一个对象的新实例,以便副本具有自己的单独副本。

     

使用clone关键字(如果可能,调用对象的__clone()方法)创建对象副本。无法直接调用对象的__clone()方法。

     

$copy_of_object = clone $object;

     

克隆对象时,PHP 5将执行所有对象属性的浅表副本。任何引用其他变量的属性都将保留引用。

尽管本手册描述了PHP 5的行为,但根据我自己的经验,我可以向您保证PHP 7的行为方式相同。

如果你需要克隆其他内容,请实现__clone方法并定义对象必须克隆的确切内容和方式。