PHP 8.3 新特性: 动态访问类常量及 Enum 成员
PHP 8.3 及其以后支持使用变量名访问类常数以及 Enum 成员。
class MyClass {
public const MY_CONST = 42;
}
$constName = 'MY_CONST';
echo MyClass::{$constName};
PHP 8.3 之前,ClassName::{$varName}
语法获取类常量是不允许的,会出现语法错误:
Parse error: syntax error, unexpected token ";", expecting "(" in ... on line ...
Enum 也有同样的限制,不能动态获取 Enum 成员:
enum MyEnum: int {
case MyMember = 42;
}
$enumName = 'MyMember';
echo MyEnum::{$enumName}->value;
Parse error: syntax error, unexpected token "->", expecting "(" in ``` on line ```
PHP 8.3 之前,访问类常量和 Enum 成员的唯一方法是 constant()
函数:
echo \constant("MyClass::$constName");
echo \constant("MyEnum::$enumName")->value;
PHP 8.3 之后允许直接动态获取类常量和 Enum 成员。这意味着导致语法错误的两个代码片段在 PHP 8.3 和更高版本中的工作效果与预期一致。
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;
{}
内的表达式不限于变量。任何返回字符串的表达式都是可以的:
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
魔术常量(返回类 /Enum 的全名)也允许使用新语法:
class Foo {}
$constant = 'class';
echo Foo::{$constant}; // "Foo"
类型错误
尝试使用返回值不是字符串的表达式获取类常量或者 Enum 成员,会导致 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 中兼容。