2016-08-06 4 views
-2

У меня такой же poblem about making a copy of an object without reference in PHP, но это решение не работает.Клонирование объекта 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 является объектом коллекции счетов-фактур, $this->extendedInvoices является методом класса счета-фактуры.

Проблема в том, что каждое изменение, сделанное в $toSaveInvoice, также влияет на исходный элемент коллекции. После 3-х итераций, дата является одинаковым для всех элементов extendedInvoices и не должно быть:

enter image description here

Я использую Laravel 5.2, но я думаю, что не помощники клонировать элемент коллекции.

Вы знаете почему clone() не работает? Большое спасибо за вашу помощь.

+2

Клон, вероятно, будет делать «мелкий клон»; вам может потребоваться создать собственный метод «__clone» для создания «глубокого клонирования» (т. е. клонирование всех вложенных объектов в вашем объекте Invoice) –

+1

хороший пример здесь: http://php.net/manual/en/language .oop5.cloning.php – dMd

ответ

1

Хорошая идея - сначала прочитать руководство и задать вопрос о SO позже.

PHP manual От:

Создание копии объекта с абсолютно идентичными свойствами не всегда нужное поведение. Хорошим примером необходимости создания конструкторов копирования является то, что если у вас есть объект, который представляет окно GTK, и объект хранит ресурс этого окна GTK, при создании дубликата вы можете создать новое окно с теми же свойствами и у нового объекта есть ресурс нового окна. Другой пример: если ваш объект содержит ссылку на другой объект, который он использует, и когда вы реплицируете родительский объект, который хотите создать новый экземпляр этого другого объекта, чтобы у реплики была своя отдельная копия.

Объектная копия создается с использованием ключевого слова clone (который вызывает метод __clone() объекта, если это возможно). Метод __clone() объекта нельзя вызвать напрямую.

$copy_of_object = clone $object;

Когда объект клонированы, PHP 5 будет выполнять неполную копию всех свойств объекта. Любые свойства, которые являются ссылками на другие переменные, останутся ссылками.

Несмотря на то, что руководство описывает поведение PHP 5, я могу с уверенностью убедить вас, что PHP 7 ведет себя одинаково.

Если вам нужно клонировать что-то еще внутри, реализуйте метод __clone и определите, что именно и как клонировать объект.