I noticed something strange when using the combination property hooks with the magic __sleep()
method. I have no idea whether I incorrectly use hooks or that this is a bug in PHP.
See the following example:
class A {
private array $foo = ['baz' => 10];
public int $bar {
get => $this->foo['baz'];
set {
$this->foo['baz'] = $value;
}
}
public function __sleep()
{
// ...
return array_keys(get_object_vars($this));
}
}
$a = new A;
$a->bar = 20;
var_dump(unserialize(serialize($a)));
This causes the following warning:
serialize(): "bar" returned as member variable from __sleep() but does not exist
Which is strange, because it works as expected and the property does exist. Reproducable example: https://3v4l.org/V1S5i#v8.4.3.
This is an issue because in the framework I use (Laravel), this warning is promoted to an exception and breaks my application.
No idea how much nitpicking about the word "member" in the error message is necessary. The diagnostic message is likely a bit surprising indeed, but hooks are new, too. Reading __sleep() it may stem from the warning returning the member name of an inaccessible parents private property. But I've not looked into the source.
If a bug, then it should be possible to serialize the property. As analyzed in comments already, it's a virtual one, and therefore it makes not much sense to serialize it (so not/a bug).
Undocumented:
In your posted example, you can replace get_object_vars() with get_mangled_object_vars(). It silently discards uninitialized typed properties (documented) and virtual properties with hooks as it seems (just learned).
References