PHP 8.3: Динамическое получение констант класса и Enum
PHP 8.3 и более поздние версии получат поддержку получение констант класса и элементов Enum через переменную с названием константы
Итак, PHP 8.3 позволит написать вот такой код:
class Invoice {
public const STATUS_COMPLETE = "complete";
}
$constName = 'STATUS_COMPLETE';
echo Invoice::{$constName}; //"complete"
До PHP 8.3 синтаксис доступа к константам класса ClassName::{$varName} был невозможен и приводил к синтаксической ошибке:
Parse error: syntax error, unexpected token ";", expecting "(" in ... on line ...
То же ограничение применялось и к Enum, где было невозможно получить динамически элемент Перечисления:
enum MyEnum: int {
case MyElement = 42;
}
$enumName = 'MyElement';
echo MyEnum::{$enumName}->value;
Parse error: syntax error, unexpected token "->", expecting "(" in ``` on line ```
Единственным способом динамического доступа к константам класса и элементам Enum до PHP 8.3 была функция constant():
echo \constant("MyClass::$constName");
echo \constant("MyEnum::$enumName")->value;
Теперь в PHP 8.3 код будет валиден и выполняться как ожидается.
Выражение внутри {} не ограничивается только полным именем переменной. Допускается любое выражение, возвращающее строковое значение:
class MyClass {
public const MY_CONST = 42;
}
$constPrefix = 'MY_';
echo MyClass::{$constPrefix . 'CONST'};
Неопределенная константа и поведение Enum
Нет никаких изменений в поведении при попытке доступа к неопределенной константе класса или элементу Enum. Оба они приводят к ошибке неопределенной константы:
Fatal error: Uncaught Error: Undefined constant MyEnum::MyMembers in ...:...
Магическая константа ::class
Магическая константа ::class, которая возвращает полное имя класса Class/Enum, также разрешены с новым синтаксисом:
class Foo {}
$constant = 'class';
echo Foo::{$constant}; // "Foo"
Ошибки типа
Попытка получить константу класса или элемент Enum с выражением, возвращающим любой тип, кроме как string вызывает исключение TypeError:
class Foo {}
$constant = 16;
echo Foo::{$constant};
Fatal error: Uncaught TypeError: Cannot use value of type int as class constant name in ...:...
Влияние обратной совместимости
До версии PHP 8.3 синтаксис ClassName::{$constantName} был запрещен и приводил к синтаксическим ошибкам. Приложения PHP, использующие этот синтаксис, не будут работать в старых версиях PHP.
Что думаешь?