В данном сценарии у меня есть класс:
class shopCart {}
Я использую там деструкторы и конструкторы для выполнения определенных действий.
Позже я хочу сохранить сериализованную версию тележки. Однако сериализация объекта я не должна включать методы деструктора и конструктора.
Для этого я создал класс:
class storageCart extends shopCart {
function __construct(){}
function __destruct(){}
}
Теперь, прежде чем я storageCart
хранить корзину, я должен создать новый объект типа storageCart
и убедиться, что он содержит все свойства shopCart
.
Чтобы выполнить эту shopCart
, у shopCart
есть метод getInstanceForStorage()
:
public function getInstanceForStorage() {
$storageCart = new storageCart();
foreach(get_object_vars($this) as $k => $v){
$storageCart->{$k}=$v;
}
return $storageCart;
}
Проблема в том, что изменения, которые я делаю для нового экземпляра (storageCart
), похоже, влияют на исходный экземпляр (shopCart
).
Здесь важно указать, что одной из переменных shopCart
является массив, содержащий объекты (элементы корзины).
Я предполагаю, что я столкнулся с каким-то беспорядком в объекте /instancing/copy/cloning (или отсутствием). Но я не знаю, в чем проблема, потому что я не использую указатели в своем назначении в вышеупомянутом цикле foreach
.
Может ли кто-нибудь пролить свет на то, что здесь происходит?
Примечание. Это PHP> 5.3
РЕДАКТИРОВАТЬ
Я попытался скопировать содержимое массива, содержащего объекты, назначив их одному и тому же массиву в новом объекте и используя clone
, но, к моему удивлению, я все еще получаю ссылку. Я не понимаю.
Возможно ли, что объекты внутри клонированных объектов все еще ссылаются на исходные объекты?
Техника, которую вы хотите, называется созданием "глубокого клона" и может быть легко реализована с использованием магического метода __clone() в ваших объектах:
/**
* Implement PHP __clone to create a deep clone, not just a shallow copy.
*/
public function __clone()
{
foreach ($this as $key => $val) {
if (is_object($val) || (is_array($val))) {
$this->{$key} = clone $val;
}
}
}
Просто определите это в своем основном классе и в классах всех объектов, которые вы храните как свойства в этом классе, полностью вниз
Конечно, если вы держите массив объектов как свойство, вам нужно будет адаптировать этот код, чтобы пройти этот массив