Serializable
インターフェイスを実装するオブジェクトに関して解決するのはかなり難しい問題でした。のは、例を見てみましょう: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
私たちは、組み込みのPHPのシリアル化機能(私たちは__sleep()
機能を使用するかどうかにかかわらず)を使用した場合、A
& B
間の相互参照を(保存されていることを、この例では見ることができますr:1;
)。
我々はSerializableインタフェースの使用を強制したい場合は、問題が発生:
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
各オブジェクトのシリアル化が独立して管理されているので、オブジェクトがすでにされているかどうかを確認するためにグローバルな方法はありませんシリアライズされ、参照を作成します。 serialize()
関数は、無限ループで呼び出されます。
この問題の適切な回避策はありますか? serialize()
機能に使用するパターン?ここで
これは素晴らしいPHP *の "機能"です。それを解決する方法を教えてもらえません。参照を割り当てようとしましたが( '$ a-> b =&$ b')、それも失敗しました。 –
これは純粋に予測可能な動作ですが、私はその解決策がユーザーコードにあると思いますが、今のところ回避策を見つけられません。 – Benjamin