これは SO に関する私の最初の質問ですが、かなり検索しました。すでに触れていたらすみません。
質問/問題は、PHP の serialize() 機能に関係しています。オブジェクトをデータベースに格納するためにシリアル化を使用しています。例えば:
class Something {
public $text = "Hello World";
}
class First {
var $MySomething;
public function __construct() {
$this->MySomething = new Something();
}
}
$first_obj = new First();
$string_to_store = serialize($first_obj);
echo $string_to_store
// Result: O:5:"First":1:{s:11:"MySomething";O:9:"Something":1:{s:4:"text";s:11:"Hello World";}}
さて、プロジェクト生活の後半で、私は自分のクラスを変更したいと思います。まず、何かのオブジェクトにも対応する新しいプロパティ $SomethingElse を持ちます。
問題は、古い/既存のオブジェクトの場合、First クラスの新しいバージョンにシリアル化を解除するときに、新しいプロパティ (SomethingElse) を初期化する唯一の方法は、__wakeup() メソッドでそれを探すことです。その場合、そこに新しいプロパティを文書化する必要があります。これは正しいです?プロパティはコンストラクタのように扱われ、初期値が設定されている必要があります (最終的にコードが複製されます)。
変数を宣言するときに変数を初期化すると、たとえば、Something クラスを次のように変更すると、シリアル化解除によって取得されることがわかりました。
class Something {
public $text = "Hello World";
public $new_text = "I would be in the unserialized old version.";
}
...
$obj = unserialize('O:5:"First":1:{s:11:"MySomething";O:9:"Something":1:{s:4:"text";s:11:"Hello World";}}');
print_r($obj);
// Result: First Object ( [MySomething] => Something Object ( [text] => Hello World [new_text] => I would be in the unserialized old version. ) )
ただし、新しいプロパティを宣言するときにオブジェクトに初期化することはできません。これは、コンストラクター (および __wakeup()?) で行う必要があります。
これを十分に説明したことを願っています。このあたりに欠けているプログラミング パターンがあるかどうか、または __wakeup() で初期化コードを複製する (または init メソッドを参照する) ことが一般的かどうか、または単に古いオブジェクトを新しいバージョンに移行する準備が必要かどうかを知りたい経由。移行スクリプト。
ありがとう。
更新: これまでのコメンターの発言を考えて、init() メソッドを使用して更新された First クラスを投稿すると思いました。
class Something {
public $text = "Hello World2";
public $new_text = "I would be in the unserialized old version.2";
}
class First {
var $MySomething;
var $SomethingElse;
public function __construct() {
$this->init();
}
public function __wakeup() {
$this->init();
}
private function init() {
if (!isset($this->MySomething)) {
$this->MySomething = new Something();
}
if (!isset($this->SomethingElse)) {
$this->SomethingElse = new Something();
}
}
}
$new_obj = unserialize('O:5:"First":1:{s:11:"MySomething";O:9:"Something":1:{s:4:"text";s:11:"Hello World";}}');
print_r($new_obj);
// Result: First Object ( [MySomething] => Something Object ( [text] => Hello World [new_text] => I would be in the unserialized old version.2 ) [SomethingElse] => Something Object ( [text] => Hello World2 [new_text] => I would be in the unserialized old version.2 ) )
それは私にとって実行可能なパターンのように思えるので、本当にわかりません。クラスが新しいプロパティを取得すると、最初の復元時にデフォルト値が取得されます。