PHP 8.4: #[Deprecated] attribute
PHP 8.4 introduces a new PHP Attribute named #[Deprecated], that can attribute a PHP function, a class method, or a class constant as deprecated.
When using a deprecated function, class, or a method with the #[Deprecated] attribute, PHP automatically emits a deprecation message. This happens for each time the function/method/constant is used.
Prior to the introduction of this attribute, the typical way of announcing deprecations of user-land PHP functions/methods/constants is by emitting a deprecation message using the trigger_error function, and/or by annotating this information in a /** @deprecated */ PHP Doc tag.
This approach was not as perfect, because the Reflection API, more specifically the ReflectionFunctionAbstract::isDeprecated() method does not return the deprecation status with the @deprecated PHP Doc annotation. With the new #[Deprecated] attribute, if a PHP symbol is deprecated, the isDeprecated method returns true if the attribute is present.
Example with a #[Deprecated] function:
#[Deprecated]
function my_deprecated_function(): void {
echo "Called";
}
my_deprecated_function();
Deprecated: Function my_deprecated_function() is deprecated in ... on line ...
Called
Example with a #[Deprecated] class method:
class Test {
#[Deprecated]
public function myMethod(): void {}
}
new Test()->myMethod();
Deprecated: Method Test::myMethod() is deprecated in ... on line ...
Example with a #[Deprecated] class constant:
class Test {
#[Deprecated]
public const int TEST = 42;
}
echo Test::TEST;
Deprecated: Constant Test::TEST is deprecated in ... on line ...
42
Example with a #[Deprecated] Enum member:
enum MyEnum {
#[Deprecated]
case Test;
}
echo MyEnum::Test->name;
Deprecated: Enum case MyEnum::Test is deprecated in ... on line ...
Test
Applicable targets for #[Deprecated] attribute
The #[Deprecated] attribute can be added to the following targets:
- Functions
- Class methods
- Class constants
- Enum members
- Constants (since PHP 8.5)
Notably, the #[Deprecated] attribute can not be used on:
- Class declarations
- Function and method parameters
#[Deprecated] attribute synopsis
#[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) {}
}
The Deprecated attribute class is declared in the global namespace. When applying the attribute, it can also be used as a fully-qualified class name: #[\Deprecated].
Specifying a custom deprecation message
By default, when a PHP symbol is attributed with the #[Deprecated] attribute, it emits a %s is deprecated deprecation message.
However, it is possible to customize this message using the two optional parameters supported by the #[Deprecated] attribute.
Example with $message parameter:
#[Deprecated("use bar instead")]
function foo(): void {}
foo();
Deprecated: Function foo() is deprecated, use bar instead in ... on line ...
Example with $message and $since parameters:
#[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 ...
Example with $message and $since as named parameters:
#[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 ...
Example with only $since parameter:
#[Deprecated(since: 'v42.16.15')]
function foo(): void {}
foo();
Deprecated: Function foo() is deprecated since v42.16.15 in ... on line ...
Reflection Functionality Changes
The new #[Deprecated] attribute does not introduce any Reflection API changes. However, the Reflection API can now return the deprecated status for user-land PHP symbols using this attribute:
#[Deprecated]
function my_deprecated_function(): void {}
$reflector = new ReflectionFunction('my_deprecated_function');
$reflector->isDeprecated(); // true
This change is effective for class methods (ReflectionMethod::isDeprecated) and class constants/Enum members (ReflectionClassConstant::isDeprecated()) as well. Note that the ReflectionClassConstant class is new in PHP 8.4.
Replacing exiting deprecation mechanisms
PHP applications running PHP 8.4 and later can safely replace deprecation mechanisms for user-land PHP functions and classes with the new #[Deprecated] attribute:
+ #[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);
}
Backward Compatibility Impact
Unless a user-land PHP application declares a PHP class named Deprecated in the global namespace, this change should not cause any backward compatibility impact.
Any PHP symbol with the #[Deprecated] attribute will continue to work on older PHP versions, but they will not trigger deprecation messages on older PHP versions.
To consistently emit deprecation messages on PHP 8.4+ and older PHP versions, the applications have to emit the deprecation notice within the function or class method itself.
#[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);
}
}