diff --git a/README.md b/README.md index 2560495d..98bb7a03 100644 --- a/README.md +++ b/README.md @@ -271,8 +271,9 @@ class CardinalDirection extends Enum implements Serializable $north1 = CardinalDirection::NORTH(); $north2 = unserialize(serialize($north1)); -// The following could be FALSE as described above -var_dump($north1 === $north2); +var_dump($north1 === $north2); // returns FALSE as described above +var_dump($north1->is($north2)); // returns TRUE - this way the two instances are treated equal +var_dump($north2->is($north1)); // returns TRUE - equality works in both directions ``` # Why not `SplEnum` diff --git a/src/Enum.php b/src/Enum.php index 061a8ab1..29d79b72 100644 --- a/src/Enum.php +++ b/src/Enum.php @@ -146,7 +146,13 @@ final public function getOrdinal() */ final public function is($enumerator) { - return $this === $enumerator || $this->value === $enumerator; + return $this === $enumerator || $this->value === $enumerator + + // The following additional conditions are required only because of the issue of serializable singletons + || ($enumerator instanceof static + && get_class($enumerator) === get_called_class() + && $enumerator->value === $this->value + ); } /** diff --git a/tests/MabeEnumTest/EnumTest.php b/tests/MabeEnumTest/EnumTest.php index 9a74c60e..4678919d 100644 --- a/tests/MabeEnumTest/EnumTest.php +++ b/tests/MabeEnumTest/EnumTest.php @@ -8,6 +8,7 @@ use MabeEnumTest\TestAsset\EnumExtendedAmbiguous; use MabeEnumTest\TestAsset\ConstVisibilityEnum; use MabeEnumTest\TestAsset\ConstVisibilityEnumExtended; +use MabeEnumTest\TestAsset\SerializableEnum; use PHPUnit_Framework_TestCase as TestCase; use ReflectionClass; @@ -285,4 +286,17 @@ public function testConstVisibilityExtended() 'PUB2' => ConstVisibilityEnumExtended::PUB2, ), $constants); } + + public function testIsSerializableIssue() + { + if (PHP_VERSION_ID < 50400) { + $this->markTestSkipped('This test is for PHP-5.4 and upper only'); + } + + $enum1 = SerializableEnum::INT(); + $enum2 = unserialize(serialize($enum1)); + + $this->assertFalse($enum1 === $enum2, 'Wrong test implementation'); + $this->assertTrue($enum1->is($enum2), 'Two different instances of exact the same enumerator should be equal'); + } }