-1

I'm having the same poblem about making a copy of an object without reference in PHP but that soluction is not working.

I want to take all elements of a collection, change one property (add months) and push that new element into a new collection.

So I've used clone in order to get a totally new instance of an Invoice wich should be affected just that instance, but is not.

With this code:

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);
}

Where $thisInvoice is an object of the Invoice collection, $this->extendedInvoices is a method of the class Invoice.

The problem is that every change done in $toSaveInvoice also affects to the original collection element. After 3 iterations, date is the same for all elements of extendedInvoices and should not be:

enter image description here

I am using Laravel 5.2, but I think there aren't helpers to clone an element of a collection.

Do you know why clone() is not working? Thanks a lot for your help.

Community
  • 1
  • 1
Joss
  • 535
  • 1
  • 8
  • 28
  • 2
    clone is likely to be doing a "shallow clone"; you may need to provide a custom magic `__clone` method to do a "deep clone" (ie, cloning all the nested objects within your Invoice object) – Mark Baker Aug 06 '16 at 18:02
  • 1
    good example here: http://php.net/manual/en/language.oop5.cloning.php –  Aug 06 '16 at 19:08

1 Answers1

3

A good idea is to read the manual first and ask a question on SO later.

From PHP manual:

Creating a copy of an object with fully replicated properties is not always the wanted behavior. A good example of the need for copy constructors, is if you have an object which represents a GTK window and the object holds the resource of this GTK window, when you create a duplicate you might want to create a new window with the same properties and have the new object hold the resource of the new window. Another example is if your object holds a reference to another object which it uses and when you replicate the parent object you want to create a new instance of this other object so that the replica has its own separate copy.

An object copy is created by using the clone keyword (which calls the object's __clone() method if possible). An object's __clone() method cannot be called directly.

$copy_of_object = clone $object;

When an object is cloned, PHP 5 will perform a shallow copy of all of the object's properties. Any properties that are references to other variables will remain references.

Even though the manual describes PHP 5 behavior, I can assure you, from my own experience, that PHP 7 behaves the same way.

If you need to clone with something else inside, implement the __clone method and define what exactly and how the object has to be cloned.

Kevin Kopf
  • 13,327
  • 14
  • 49
  • 66