2

Is it possible to access enumerations properties dynamically?

Here is what I tried and the error I got.

Access to undeclared static property ExampleEnum::$id

enum ExampleEnum
{
    case _1;
    case _2;

    public function getIt(): string
    {
        return match ($this) {
            ExampleEnum::_1 => 'foo',
            ExampleEnum::_2 => 'bar',
        };
    }
}

$id = "_1";
ExampleEnum::$id->getIt();
medilies
  • 1,811
  • 1
  • 8
  • 32

1 Answers1

5

It's important to distinguish between three different things here:

  • A class property would be declared in a class as static $foo (with optional visibility, type, and default value), and accessed as Example::$foo. Dynamically, you could access that with "variable-variable" syntax, e.g. $name = 'foo'; echo Example::$$name;.
  • A class constant would be declared as const foo = 'value' (with optional visibility), and accessed as Example::foo. There is no direct syntax for accessing it directly, but you can use the constant function, as in $name = 'foo'; echo constant("Example::$name");
  • An enum case is declared as case foo (with a value if using a "backed enum"), and it is accessed using the same syntax as a class constant.

In fact, it is treated like a constant in many ways, and a test shows that the constant function can actually be used to look one up, so this will work:

enum ExampleEnum
{
    case _1;
    case _2;

    public function getIt(): string
    {
        return match ($this) {
            ExampleEnum::_1 => 'foo',
            ExampleEnum::_2 => 'bar',
        };
    }
}

$id = "_1";
echo constant("ExampleEnum::$id")->getIt();

Note that if you use a "backed enumeration", you can associate an arbitrary integer or string with each case, separate from its name, and use the from method to look up a case based on that value.

IMSoP
  • 89,526
  • 13
  • 117
  • 169