diff --git a/src/Enum.php b/src/Enum.php index b0d764f..81c7821 100644 --- a/src/Enum.php +++ b/src/Enum.php @@ -18,7 +18,9 @@ class Enum implements EnumInterface { /** @var array */ - private static array $constants; + private static array $constants = []; + + protected static array $instances = []; /** @var mixed */ private mixed $value; @@ -33,11 +35,10 @@ class Enum implements EnumInterface */ final public function __construct(mixed $value) { - static::$constants = static::constants(); - $value = ($value instanceof EnumInterface) ? $value->getValue() : $value; $this->key = static::searchNameByValue($value); + $this->value = $value; } @@ -46,9 +47,15 @@ final public function __construct(mixed $value) */ private static function constants(): array { + if (isset(static::$constants[static::class])) { + return static::$constants[static::class]; + } + $reflection = new ReflectionClass(static::class); - return $reflection->getConstants(); + static::$constants[static::class] = $reflection->getConstants(); + + return static::$constants[static::class]; } /** @@ -65,7 +72,7 @@ public function getValue(): mixed */ private static function searchNameByValue(mixed $value): string { - $name = array_search($value, static::$constants, true); + $name = array_search($value, static::constants(), true); if (false === $name) { throw new InvalidArgumentException(sprintf('Constant value [%s] not found', $value)); } @@ -80,11 +87,16 @@ private static function searchNameByValue(mixed $value): string */ final public static function __callStatic(string $name, array $arguments): self { - if (!array_key_exists($name, static::$constants)) { + if (!array_key_exists($name, static::constants())) { throw new InvalidArgumentException(sprintf('Constant [%s] is not defined', $name)); } + if (isset(static::$instances[static::class][$name])) { + return static::$instances[static::class][$name]; + } + + static::$instances[static::class][$name] = new static(static::constants()[$name]); - return new static(static::$constants[$name]); + return static::$instances[static::class][$name]; } /** @@ -92,7 +104,7 @@ final public static function __callStatic(string $name, array $arguments): self */ public function getValues(): array { - return array_values(static::$constants); + return array_values(static::$constants[static::class]); } /** @@ -100,7 +112,7 @@ public function getValues(): array */ public function getKeys(): array { - return array_keys(static::$constants); + return array_keys(static::$constants[static::class]); } /** @@ -116,7 +128,7 @@ public function getKey(): string */ public function toArray(): array { - return static::$constants; + return static::$constants[static::class]; } /** diff --git a/tests/EnumTest.php b/tests/EnumTest.php index f04ed0a..6bbc736 100644 --- a/tests/EnumTest.php +++ b/tests/EnumTest.php @@ -53,7 +53,7 @@ public function invalidMethod(): void public function keysValues(): void { $this->enum = new DummyEnum(5); - static::assertEquals(["VALUE", "OTHER", "PRODUCT"], $this->enum->getKeys()); + static::assertEquals(["VALUE1", "VALUE2", "VALUE5"], $this->enum->getKeys()); static::assertEquals([0 => 1, 1=> 2, 2=> 5], $this->enum->getValues()); } @@ -66,22 +66,22 @@ public function callDataProvider(): array return [ [ - "1", $this->enum::VALUE() + "1", $this->enum::VALUE1() ], [ - "2", $this->enum::OTHER(), + "2", $this->enum::VALUE2(), ], [ "5", new DummyEnum(new DummyEnum(5)), ], [ - 5, $this->enum->getValue(), + "5", $this->enum->getValue(), ], [ - "PRODUCT", $this->enum->getKey(), + "VALUE5", $this->enum->getKey(), ], [ - ["VALUE" => 1, "OTHER" => 2, "PRODUCT" => 5], $this->enum->toArray(), + ["VALUE1" => 1, "VALUE2" => 2, "VALUE5" => 5], $this->enum->toArray(), ] ]; } @@ -96,9 +96,9 @@ public function callDataProvider(): array */ class DummyEnum extends Enum { - public const VALUE = 1; + public const VALUE1 = 1; - public const OTHER = 2; + public const VALUE2 = 2; - public const PRODUCT = 5; + public const VALUE5 = 5; }