__clone () против несериализации (serialize ())? - PullRequest
4 голосов
/ 11 февраля 2011

со ссылкой на этот вопрос я получил другое решение использовать

$obj2 = unserialize(serialize($obj1));

вместо

$obj2 = clone $obj1;

Какой из них лучше использовать?

Ответы [ 2 ]

10 голосов
/ 11 февраля 2011

tl; dr версия: Используйте clone для простых объектов и деревьев, unserialize(serialize()) для сложных графиков объектов.

Более подробное объяснение: Если $obj1 не реализует __clone(), выражение clone $obj1 возвратит поверхностную копию $obj1, но с общим содержимым объектов, на которые указывает $obj1. Даже если __clone() реализован для выполнения глубокого копирования рекурсивными clone членами, он будет работать безопасно, только если граф объектов является деревом. Если граф объектов содержит циклы, он будет повторяться бесконечно и ... ну ... это переполнение стека по причине. :-) Если это ориентированный ациклический граф, но не дерево, любой объект, на который ссылаются несколько раз, заменяет эти множественные ссылки на копии, что может быть не тем, что вам нужно.

unserialize(serialize($obj1)), с другой стороны, будет иметь дело с циклами в графе объектов, но дороже с точки зрения времени процессора и памяти.

3 голосов
/ 11 февраля 2011

Конечно, это создает клона, но с невероятными накладными расходами и без возможности фактически определять какие-либо настройки или поведения, используя магический метод __clone.

Я бы использовал ключевое слово clone, и если вам нужны дальнейшие исследования, см. Раздел комментариев на http://php.net/manual/en/language.oop5.cloning.php, чтобы получить доказательства того, что клонирование не требует, чтобы изменение одного объекта сохранялось в его клоне.

...