既に説明したように、はオブジェクトを取得し__sleep()
たときに呼び出され、その後に呼び出されます。serialize()
__wakeup()
unserialize()
シリアライゼーションは、オブジェクトを永続化するために使用されます。オブジェクトの表現を文字列として取得し$_SESSION
、データベース、Cookie、またはその他の必要な場所に格納できます。
リソース値
ただし、リソース タイプの値をシリアル化 (つまり、テキスト表現に変換) するserialize()
ことはできません。これが、これらの値がすべてing後に失われる理由です。unserialize()
オブジェクトグラフ
またはメンバー、およびメンバーのメンバーと ... 無限
もう 1 つの、おそらくより重要な点は、オブジェクト グラフをシリアル化するとserialize()
、オブジェクト グラフ全体をトラバースすることです。$obj
これは必要な場合には便利ですが、オブジェクトの一部だけが必要で、特定のリンクされたオブジェクトが「ランタイム固有」であり、多くのオブジェクトだけでなく他のオブジェクトでも共有されている場合は、その動作が望ましくない場合があります。
PHP は循環グラフを正しく処理します! 意味: $a (のメンバー) が $b にリンクし、$b が $a にリンクしている場合、何レベル深くても正しく処理されます。
例 - セッション固有の (共有) オブジェクト
たとえば、$database
オブジェクトは によって参照されますが$obj->db
、他のオブジェクトによっても参照されます。データベース オブジェクトの分離されたインスタンスではなく、次のセッションの他のすべての$obj->db
オブジェクトと同じオブジェクトになりたいと思うでしょう。unserialize()
この場合、次__sleep()
のような方法があります。
/**
/* DB instance will be replaced with the one from the current session once unserialized()
*/
public function __sleep() {
unset($this->db);
}
そして、次のように復元します。
public function __wakeup() {
$this->db = <acquire this session's db object>
}
もう 1 つの可能性は、オブジェクトが、登録が必要な (グローバル) データ構造の一部であるということです。もちろん、これを手動で行うこともできます:
$obj = unserialize($serialized_obj);
Thing::register($obj);
ただし、それがそのレジストリに存在する必要があるオブジェクト契約の一部である場合、この魔法の呼び出しをオブジェクトのユーザーに任せるのはお勧めできません。理想的な解決策は、オブジェクトがその責任を気にしている場合、つまり に登録されている場合Thing
です。これ__wakeup()
により、クライアントに対して透過的に (つまり、魔法のような依存関係について心配する必要がなくなります) ことができます。
同様に、必要に__sleep()
応じてオブジェクトを「登録解除」するために使用できます。(オブジェクトはシリアライズされても破棄されませんが、状況によっては意味があるかもしれません。)
閉鎖
最後になりましたが、クロージャーはシリアル化もサポートしていません。これは、アタッチされているすべてのクロージャを で再作成する必要があることを意味します__wakeup()
。