Open ukhvan opened 7 years ago
Here's an example of how it can be done, using the Planet
multiton from the README:
class SerializableObject implements Serializable
{
public function __construct(Planet $planet)
{
$this->planet = $planet;
}
public function serialize()
{
return serialize(['planet' => $this->planet->key()]);
}
public function unserialize($serialized)
{
$data = unserialize($serialized);
$this->planet = Planet::memberByKey($data['planet']);
}
}
$object = new SerializableObject(Planet::EARTH());
$serialized = serialize($object);
$unserialized = unserialize($serialized);
var_dump($object->planet === $unserialized->planet); // outputs bool(true)
Thank you for your answer! It's a pity that it's impossible to make the Planet class itself serializable, and instead, one has to care about its serialization in all client classes which use it. Thank you for the example you've provided though.
No worries. To explain why this is the only option:
PHP only allows you to modify the properties of the object being unserialized, it's impossible to change which instance is returned. Unserializing a particular multiton member twice would produce two separate instances, which breaks the core functionality of this library.
AbstractMultiton
should probably implement Serializable
and throw an exception to prevent unexpected problems arising from this issue.
Unserializing a particular multiton member twice would produce two separate instances, which breaks the core functionality of this library.
Thus, the only option to make serializable enumeration is to make it non-multitons, but regular objects, and compare them not via strict comparison operator ===
, but via calling Java-style equals
method like this: $planet->equals(Planet::Earth())
— which will not break the core functionality of this library, but will change the strategy of comparison of enumeration instances.
Again, thank you for your answer, it clarified my view on this problem.
AbstractMultiton should probably implement Serializable and throw an exception
Completely agree with you in this.
You're welcome. On a side note, the README does mention strict equality:
For each member of the enumeration, a single instance of the enumeration class is instantiated (that is, an instance of
HttpRequestMethod
in the above example). This means that strict comparison (===) can be used to determine which member has been passed to a function:function handleHttpRequest(HttpRequestMethod $method, $url, $body = null) { if ($method === HttpRequestMethod::POST()) { // handle POST requests... } else { // handle other requests... } }
What is the correct way to use your library in serializable object? Especially, Multiton class. Is it possible? The constructor is protected, thus, there are some difficulties…