From a2bdae85c7b8c83124c203853d7c3bf4b4115c52 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Tue, 14 May 2019 07:22:20 +0200 Subject: [PATCH] PHP 7.4 serializer and wrap old Serializable methods for BC --- src/EnumSerializableTrait.php | 59 +++++++++++++++---- .../EnumSerializableTraitTest.php | 14 ++++- 2 files changed, 58 insertions(+), 15 deletions(-) diff --git a/src/EnumSerializableTrait.php b/src/EnumSerializableTrait.php index a791aed6..55096ce1 100644 --- a/src/EnumSerializableTrait.php +++ b/src/EnumSerializableTrait.php @@ -29,27 +29,34 @@ trait EnumSerializableTrait abstract public function getValue(); /** - * Serialized the value of the enumeration - * This will be called automatically on `serialize()` if the enumeration implements the `Serializable` interface - * @return string + * Returns an array of data to be serialized. + * This magic method will be called by serialize() in PHP >= 7.4 + * + * @return array */ - public function serialize(): string + public function __serialize(): array { - return \serialize($this->getValue()); + return ['value' => $this->getValue()]; } /** - * Unserializes a given serialized value and push it into the current instance - * This will be called automatically on `unserialize()` if the enumeration implements the `Serializable` interface - * @param string $serialized + * Receives an array of data to be unserialized on a new instance without constructor. + * This magic method will be called in PHP >= 7.4 is the data where serialized with PHP >= 7.4. + * + * @throws RuntimeException On missing, unknown or invalid value + * @throws LogicException On calling this method on an already initialized enumerator + * + * @param array $data * @return void - * @throws RuntimeException On an unknown or invalid value - * @throws LogicException On changing numeration value by calling this directly */ - public function unserialize($serialized): void + public function __unserialize(array $data): void { - $value = \unserialize($serialized); - $constants = static::getConstants(); + if (!\array_key_exists('value', $data)) { + throw new RuntimeException('Missing array key "value"'); + } + + $value = $data['value']; + $constants = self::getConstants(); $name = \array_search($value, $constants, true); if ($name === false) { $message = \is_scalar($value) @@ -73,4 +80,30 @@ public function unserialize($serialized): void }; $closure->bindTo($this, Enum::class)(); } + + /** + * Serialize the value of the enumeration + * This will be called automatically on `serialize()` if the enumeration implements the `Serializable` interface + * + * @return string + * @deprecated Since PHP 7.4 + */ + public function serialize(): string + { + return \serialize($this->getValue()); + } + + /** + * Unserializes a given serialized value and push it into the current instance + * This will be called automatically on `unserialize()` if the enumeration implements the `Serializable` interface + * @param string $serialized + * @return void + * @throws RuntimeException On an unknown or invalid value + * @throws LogicException On calling this method on an already initialized enumerator + * @deprecated Since PHP 7.4 + */ + public function unserialize($serialized): void + { + $this->__unserialize(['value' => \unserialize($serialized)]); + } } diff --git a/tests/MabeEnumTest/EnumSerializableTraitTest.php b/tests/MabeEnumTest/EnumSerializableTraitTest.php index ba502c84..547c0fde 100644 --- a/tests/MabeEnumTest/EnumSerializableTraitTest.php +++ b/tests/MabeEnumTest/EnumSerializableTraitTest.php @@ -62,9 +62,11 @@ public function testUnserializeThrowsRuntimeExceptionOnInvalidValue() public function testUnserializeThrowsLogicExceptionOnChangingValue() { + $enumInt = SerializableEnum::get(SerializableEnum::INT); + $enumStrSer = SerializableEnum::STR()->__serialize(); + $this->expectException(LogicException::class); - $enum = SerializableEnum::get(SerializableEnum::INT); - $enum->unserialize(serialize(SerializableEnum::STR)); + $enumInt->__unserialize($enumStrSer); } public function testInheritence() @@ -79,6 +81,14 @@ public function testInheritence() $this->assertSame($enum->getValue(), $unserialized->getValue()); } + public function testUnserializeFromPhp73() + { + $serialized = 'C:39:"MabeEnumTest\TestAsset\SerializableEnum":2:{N;}'; + $unserialized = unserialize($serialized); + $this->assertInstanceOf(SerializableEnum::class, $unserialized); + $this->assertNull($unserialized->getValue()); + } + /** * Clears all instantiated enumerations and detected constants of the given enumerator * @param string $enumeration