PHP 8.3: Dynamic class constant and Enum member fetch support

Version8.3
TypeNew Feature

PHP 8.3 and later supports fetching class constants and Enum objects with a variable name.

class MyClass {
    public const MY_CONST = 42;
}

$constName = 'MY_CONST';

echo MyClass::{$constName};

Prior to PHP 8.3, the ClassName::{$varName} syntax of accessing class constants was not allowed, and resulted in a syntax error:

Parse error: syntax error, unexpected token ";", expecting "(" in ... on line ...

The same restriction applied to Enums as well, where it was not possible to retrieve an Enum member dynamically:

enum MyEnum: int {
    case MyMember = 42;
}

$enumName = 'MyMember';

echo MyEnum::{$enumName}->value;
Parse error: syntax error, unexpected token "->", expecting "(" in ``` on line ```

The only way to access class constants and Enum members prior to PHP 8.3 was the constant() function:

echo \constant("MyClass::$constName");
echo \constant("MyEnum::$enumName")->value;

PHP 8.3 and later allows the direct dynamic class constants and Enum member fetching. This means that the two snippets that resulted in syntax errors work as expected in PHP 8.3 and later.

  class MyClass {
      public const MY_CONST = 42;
  }

  $constName = 'MY_CONST';

- echo \constant("MyClass::$constName");
+ echo MyClass::{$constName}; 
 enum MyEnum: int {
     case MyMember = 42;
 }

 $enumName = 'MyMember';

- echo \constant("MyEnum::$enumName")->value;
+ echo MyEnum::{$enumName}->value;

The expression inside the {} is not limited to a variable name. Any expression that returns a string is allowed:

class MyClass {
    public const MY_CONST = 42;
}

$constPrefix = 'MY_';

echo MyClass::{$constPrefix . 'CONST'};

Undefined Constant and Enum Behavior

There are no changes in the behavior when attempting to access an undefined class constant or an Enum member. Both of them result in an undefined constant error:

Fatal error: Uncaught Error: Undefined constant MyEnum::MyMembers in ...:...

::class Magic Constant

::class magic constants, which returns the fully-qualified class name of the Class/Enum is allowed with the new syntax as well:

class Foo {}
$constant = 'class';

echo Foo::{$constant}; // "Foo"

Type errors

Attempting to fetch a class constant or an Enum member with an expression that returns any type other than string causes a TypeError exception.

class Foo {}
$constant = 16;

echo Foo::{$constant};
Fatal error: Uncaught TypeError: Cannot use value of type int as class constant name in ...:...

Backwards Compatibility Impact

Prior to PHP 8.3, the ClassName::{$constantName} syntax was not allowed, and resulted in syntax errors. PHP applications that use this syntax do not compile in older PHP versions.


RFC Discussion Implementation