3v4l.org

run code in 300+ PHP versions simultaneously
<?php abstract class Enum { private $name; private static $enums; private function __construct($name) { $this->name = $name; } /** * Returns an assoc. array of ['ENUM_NAME' => $ENUM_VALUE] for all enum values. * @return array */ public static function getAll(): array { $class = static::class; if (!isset(self::$enums[$class])) static::init(); return self::$enums[$class]; } /** * Return an enum value (object) from a string name. * @return $this */ public static function fromString($name) { return static::__callStatic($name, []); } public function __toString() { return $this->name; } public static function __callStatic($name, $args) { $class = static::class; if (!isset(self::$enums[$class])) static::init(); if (!isset(self::$enums[$class][$name])) { throw new \TypeError('Undefined enum ' . $class . '::' . $name . '()'); } return self::$enums[$class][$name]; } private static function init() { $class = static::class; if ($class === __CLASS__) { throw new \Exception('Do not invoke methods directly on class Enum.'); } $doc = (new \ReflectionClass($class))->getDocComment(); if (preg_match_all('/@method\s+static\s+(\w+)/i', $doc, $matches)) { foreach ($matches[1] as $name) { self::$enums[$class][$name] = new static($name); } } else { throw new \Exception('Please provide a PHPDoc for ' . $class . ' with a static @method for each enum value.'); } } } /** * @method static RED() * @method static GREEN() * @method static BLUE() */ class Color extends Enum {} $red = Color::RED(); $red2 = Color::RED(); $green = Color::GREEN(); var_dump($red === $red2); var_dump($red == $red2); var_dump($red === $green); var_dump($red == $green); var_dump((string) $red); var_dump((string) $green); var_dump($red === Color::fromString('RED')); var_dump(Color::getAll()); try { $geern = Color::GEERN(); // Intentional typo. Throws. } catch (\Throwable $e) { echo get_class($e) . ': ' . $e->getMessage(). "\n"; } try { Enum::getAll(); // Shouldn't call methods directly on Enum. Throws. } catch (\Throwable $e) { echo get_class($e) . ': ' . $e->getMessage(). "\n"; }

preferences:
60.92 ms | 402 KiB | 5 Q