PHP 8.4:#[Deprecated] 注解
PHP 8.4 引入了一个 名为 #[Deprecated]
的新注解,它可以用于标记 PHP 函数、类方法或类常量为已弃用。
当使用带有 #[Deprecated]
属性的已弃用函数、类或方法时,PHP 会自动发出弃用消息。每次调用该函数/方法/常量时都会触发这条消息。
在引入此属性之前,通常通过使用 trigger_error
函数发出弃用消息和/或在 /** @deprecated */
PHP 文档注释中标记这些信息来发布用户自定义 PHP 函数/方法/常量的弃用。
这种方法并不完美,因为反射 API,特别是 ReflectionFunctionAbstract::isDeprecated()
方法,并不会返回带有 @deprecated
PHP 文档注释的弃用状态。有了新的 #[Deprecated]
属性,如果一个 PHP 符号被弃用,则 isDeprecated
方法会在存在该属性时返回 true
。
带有 #[Deprecated]
属性的函数示例:
#[Deprecated]
function my_deprecated_function(): void {
echo "Called";
}
my_deprecated_function();
Deprecated: Function my_deprecated_function() is deprecated in ... on line ...
Called
带有 #[Deprecated]
属性的类方法示例:
class Test {
#[Deprecated]
public function myMethod(): void {}
}
new Test()->myMethod();
Deprecated: Method Test::myMethod() is deprecated in ... on line ...
带有 #[Deprecated]
属性的类常量示例:
class Test {
#[Deprecated]
public const int TEST = 42;
}
echo Test::TEST;
Deprecated: Constant Test::TEST is deprecated in ... on line ...
42
带有 #[Deprecated]
属性的枚举成员示例:
enum MyEnum {
#[Deprecated]
case Test;
}
echo MyEnum::Test->name;
Deprecated: Enum case MyEnum::Test is deprecated in ... on line ...
Test
#[Deprecated]
属性适用的目标
#[Deprecated]
属性可以添加到以下目标:
- 函数
- 类方法
- 类常量
- 枚举成员
- 常量(自 PHP 8.5 起)
值得注意的是,#[Deprecated]
属性不能用于:
- 类声明
- 函数和方法参数
#[Deprecated]
属性概述
#[Attribute(Attribute::TARGET_METHOD|Attribute::TARGET_FUNCTION|Attribute::TARGET_CLASS_CONSTANT)]
final class Deprecated
{
public readonly ?string $message;
public readonly ?string $since;
public function __construct(?string $message = null, ?string $since = null) {}
}
Deprecated
属性类声明在全局命名空间中。应用该属性时,也可以使用完全限定的类名:#[\Deprecated]
。
指定自定义弃用消息
默认情况下,当 PHP 符号带有 #[Deprecated]
属性时,它会发出一条 %s is deprecated
的弃用消息。
但是,可以使用 #[Deprecated]
属性支持的两个可选参数来自定义此消息。
带有 $message
参数的示例:
#[Deprecated("use bar instead")]
function foo(): void {}
foo();
Deprecated: Function foo() is deprecated, use bar instead in ... on line ...
带有 $message
和 $since
参数的示例:
#[Deprecated('use bar instead', 'v42.16.15')]
function foo(): void {}
foo();
Deprecated: Function foo() is deprecated since v42.16.15, use bar instead in ... on line ...
带有 $message
和 $since
命名参数的示例:
#[Deprecated(message: 'use bar instead', since: 'v42.16.15')]
function foo(): void {}
foo();
Deprecated: Function foo() is deprecated since v42.16.15, use bar instead in ... on line ...
仅带有 $since
参数的示例:
#[Deprecated(since: 'v42.16.15')]
function foo(): void {}
foo();
Deprecated: Function foo() is deprecated since v42.16.15 in ... on line ...
反射函数变更
这一新增 #[Deprecated]
注解不引入任何反射 API 变更。不过,反射 API 现在现在可以使用该属性返回用户空间 PHP 符号的弃用状态:
#[Deprecated]
function my_deprecated_function(): void {}
$reflector = new ReflectionFunction('my_deprecated_function');
$reflector->isDeprecated(); // true
此更改对类方法(ReflectionMethod::isDeprecated
) 和类常量/枚举成员(ReflectionClassConstant::isDeprecated()
) 也有效。请注意, ReflectionClassConstant
类是 PHP 8.4 中的新类。
替代现有的弃用机制
运行 PHP 8.4 以上版本的应用可以使用新增的 #[Deprecated]
属性安全地为用户空间 PHP 函数和类替换弃用机制:
+ #[Deprecated('use bar instead', 'v42.16.15')]
function foo(): void {
- trigger_error('Function foo() is deprecated since v42.16.15, use bar instead', E_USER_DEPRECATED);
}
向后兼容性影响
除非用户空间 PHP 应用在全局命名空间中声明了名为 Deprecated
的类,否则该变更不会造成任何向后兼容性影响。
任何使用 #[Deprecated]
属性注解的 PHP 符号将继续在旧版 PHP 中工作,只是不会触发弃用消息。
为了在 PHP 8.4+ 和更早的 PHP 版本上持续发出弃用消息,应用必须在函数或类方法本身中发出弃用通知。
#[Deprecated('use bar instead', 'v42.16.15')]
function foo(): void {
if (\PHP_VERSION_ID < 80400) {
trigger_error('Function foo() is deprecated since v42.16.15, use bar instead', E_USER_DEPRECATED);
}
}