rfc:deprecated_attribute

PHP RFC: #[Deprecated] Attribute

Introduction

With the Attributes RFC accepted for PHP 8, this is a first proposal for an internal attribute hooking into the engine. It allows to mark functions and methods as deprecated with the same mechanism that the engine and extensions already support for many years.

The benefit of using a declarative attribute to mark deprecations over either docblock, trigger_error or a combination of both is that it provides both a human and a machine readable note about deprecation. This allows human readers, static analysis tools, IDEs and the runtime of PHP to rely on a single bit of information instead of multiple different ones.

It also serves as a good prototype and first step, as usually all languages with attributes also have a Deprecated attribute in their language core.

Proposal

Developers can put an attribute #[Deprecated] on the following elements (targets):

  • Functions
  • Methods

For now is not possible to target classes, constants, properties or arguments with this attribute, and it is left for future RFC(s) to address this.

When this attribute is present, during the compile step the existing “ZEND_ACC_DEPERACTED” function flag is added to the op_array (userland function), which will automatically (with only small changes to the VM) lead to a deprecation warning when the function is called at runtime.

This functionality is present for internal functions already. The Deprecaed attribute allows to expose this feature to userland functions/methods and closes a gap between internal and userland functions.

<?php
 
use Deprecated;
 
#[Deprecated]
function test() {}
// Deprecated: Function test() is deprecated
 
#[Deprecated("use test3() instead")]
function test2() {}
// Deprecated: Function test2() is deprecated, use test3() instead
 
class Foo {
    #[Deprecated]
    public function test() {}
    // Deprecated: Method Foo::test() is deprecated in %s
}

The deprecated class is final and cannot be extended.

Runtime Effects

Using the deprecated attribute on a function or method behaves the same as putting a call to trigger_error using E_DEPRECATED level as the first line of the same function/method.

While other languages have deprecation attributes, they usually generate compile time warnings instead of runtime warnings. However as PHPs current deprecation model is based on runtime warnings, the Deprecation attribute builds on that existing model. The benefit of a declarative approach with an attribute over the current approach with a function call to trigger_error is that is that it abstracts the implementation details of how deprecations work, with the potential for better integration with future changes to the runtime warning stack of PHP.

Changes to the runtime warning stack of PHP are out of the scope of this RFC.

Backward Incompatible Changes

A class with the name “Deprecated” is introduced into the global namespace.

Proposed PHP Version(s)

8.1 for function/method deprecations

RFC Impact

To SAPIs

None

To Existing Extensions

None

To Opcache

None

New Constants

None

php.ini Defaults

None

Open Issues

Proposed Voting Choices

Accept #[Deprecated] attribute into core?

Patches and Tests

https://github.com/php/php-src/pull/6521

No implementation for deprecated class constants, properties and parameters yet.

rfc/deprecated_attribute.txt · Last modified: 2020/12/19 10:44 by beberlei