Tôi đã gặp một vấn đề khá khó khăn để giải quyết các đối tượng thực hiện giao diện Serializable
. Chúng ta hãy lấy một ví dụ:Duy trì các mối quan hệ đối tượng với việc tuần tự hóa PHP
class A {
public $b;
}
class B {
public $a;
}
$a = new A;
$b = new B;
$a->b = $b;
$b->a = $a;
echo serialize($a); // O:1:"A":1:{s:1:"b";O:1:"B":1:{s:1:"a";r:1;}}
echo serialize($b); // O:1:"B":1:{s:1:"a";O:1:"A":1:{s:1:"b";r:1;}}
$a = unserialize(serialize($a));
var_export($a === $a->b->a); // true
Chúng ta có thể thấy trong ví dụ này, rằng khi sử dụng tích hợp tính năng PHP serialization (đã hoặc chưa chúng tôi sử dụng __sleep()
chức năng), các tài liệu tham khảo chéo giữa A
& B
được bảo quản (r:1;
).
Tuy nhiên, nếu chúng ta muốn thực thi việc sử dụng các giao diện Serializable, vấn đề đặt ra:
class A implements Serializable {
public $b;
public function serialize() { return serialize($this->b); }
public function unserialize($s) { $this->b = unserialize($s); }
}
class B implements Serializable {
public $a;
public function serialize() { return serialize($this->a); }
public function unserialize($s) { $this->a = unserialize($s); }
}
$a = new A;
$b = new B;
$a->b = $b;
$b->a = $a;
echo serialize($a); // infinite loop crashes PHP
Bởi vì mỗi đối tượng serialization được quản lý một cách độc lập, không có cách nào toàn cầu để xem liệu một đối tượng đã được được tuần tự hóa, để tạo một tham chiếu đến nó. Các hàm serialize()
sau đó được gọi trong một vòng lặp vô hạn.
Có giải pháp tốt cho vấn đề này không? Một mẫu để sử dụng cho các chức năng serialize()
?
Đó là một tính năng PHP * mới "đẹp" * mà bạn tìm thấy ở đó. Mặc dù vậy, không thể cho bạn biết cách giải quyết. Tôi đã thử gán tham chiếu ('$ a-> b = & $ b'), nhưng điều đó cũng không thành công. –
Đó là một hành vi hoàn toàn có thể dự đoán được, tôi nghĩ rằng giải pháp nằm trong mã người dùng, nhưng không thể tìm thấy cách thông minh để giải quyết vấn đề đó ngay bây giờ. – Benjamin