Reputation: 666
According to the docs
when an old instance of a class that implements this interface now, which had been serialized before the class implemeted the interface, is unserialized, __wakeup() is called instead of the unserialize method, which might be useful for migration purposes.
I thought that's quite clever and useful and wanted to check it out. Unfortunately it didn't work for me and I wonder whether there's something I'm doing wrong or whether there's a bug.
Test code:
//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);
It crashes with:
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)
In essence, I serialised the $foo
object without and with the \Serializable
interface. Then added the interface and tried to unserialize()
the object serialised in the previous form (note that the serialised string starting with O
is without the interface, while the one starting with C
is with the interface).
Is there something I'm doing wrong here? Or maybe I misunderstood the docs?
Interestingly, the code runs fine on hhvm at 3v4l.org
Upvotes: 1
Views: 825
Reputation: 7236
That IS the MAIN difference between default serialization and one from the interface - by default it serializes the entire object, but with implementation of interface you define how to serialize already created object' attributes.
As such, the resulting string is going to be different due to internal implementation - as you can see in one case it's starting with "O", and in the other it's "C". Because of that you'll have to do saving of it again.
Upvotes: 1