ドキュメントによると
クラスがインターフェイスを実装する前にシリアル化されていた、このインターフェイスを現在実装しているクラスの古いインスタンスがシリアル化されていない場合、unserializeメソッドの代わりに__wakeup()が呼び出されます。これは、移行の目的で役立つ場合があります。
それはとても賢くて便利だと思い、チェックしたいと思いました。残念ながら、それは私にとってはうまくいきませんでした。私が間違っていることがあるのか、それともバグがあるのか疑問に思います。
テストコード:
//class Foo
class Foo implements \Serializable
{
public $a = 'lorem';
public function __wakeup()
{
fprintf(STDOUT, "in %s\n", __METHOD__);
}
public function serialize()
{
fprintf(STDOUT, "in %s\n", __METHOD__);
return serialize([
$this->a,
]);
}
public function unserialize($serialized)
{
fprintf(STDOUT, "in %s\n", __METHOD__);
list(
$this->a,
) = unserialize($serialized);
}
}
//$foo = new Foo();
//var_dump(serialize($foo));
//exit;
$serialised = 'O:3:"Foo":1:{s:1:"a";s:5:"lorem";}';
//$serialised = 'C:3:"Foo":22:{a:1:{i:0;s:5:"lorem";}}';
$foo = unserialize($serialised);
var_dump($foo);
クラッシュします:
Warning: Erroneous data format for unserializing 'Foo' in /in/SHaCP on line 39
Notice: unserialize(): Error at offset 13 of 34 bytes in /in/SHaCP on line 39
bool(false)
本質的に、私$foo
は\Serializable
インターフェイスの有無にかかわらずオブジェクトをシリアル化しました。次に、インターフェイスを追加unserialize()
し、前の形式でシリアル化されたオブジェクトを試行しました(で始まるシリアル化された文字列にO
はインターフェイスがなく、で始まる文字列はインターフェイスがあることに注意してくださいC
)。
ここで私が間違っていることはありますか?または多分私はドキュメントを誤解しましたか?
興味深いことに、コードは3v4l.orgのhhvmで正常に実行されます
これが、デフォルトのシリアル化とインターフェイスからのシリアル化の主な違いです。デフォルトでは、オブジェクト全体がシリアル化されますが、インターフェイスの実装では、作成済みのオブジェクトの属性をシリアル化する方法を定義します。
そのため、結果の文字列は内部実装のために異なります。ある場合は「O」で始まり、別の場合は「C」で始まります。そのため、もう一度保存する必要があります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加