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 Compile cycle.

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:

  • Functions/Methods
  • Parameters
  • Constants
  • Properties

This will lead to the following behavior:

  • For functions or methods, at compile time a new “trigger_error” function call will be injected into the generated AST and opcodes.
  • For parameters, at compile time a new trigger_error function will be injected into the generated AST and opcodes when the deprecated argument was passed by the caller.
  • For class constants, when the constant is accessed at runtime, a trigger_error deprecation will be emitted.
  • For properties, when the property is accessed at runtime, a trigger_error deprecation will be emitted.

For functions/methods/parameters, this behavior can already be achieved by writing out the trigger_error() call yourself, but specifying it as attribute/metadata allows static analysis tools, editors and IDEs to share the same information with compile-time/runtime. It serves as a de-duplication of both @deprecated doc-block tag and trigger_error invocation.

For class constants and properties, it is not currently possible to mark their use as deprecated for developers. Only document it with @deprecated. This change would require to be efficient to existing non deprecated properties and class constants, otherwise the potential overhead can probably not be justified.

<?php
 
<<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
 
    public function test2(<<Deprecated>> $value) {}
    // When $foo->test2("bar")
    // Deprecated: Argument #1 ($value) to method Foo::test() is deprecated
 
    <<Deprecated>>
    public $value;
    // When reading or writing $foo->value
    // Deprecated: Property Foo::$value is deprecated
 
    <<Deprecated>>
    const FOO = 1;
    // when reading Foo::FOO
    // Deprecated: Constant Foo::FOO is deprecated
}

Backward Incompatible Changes

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

Proposed PHP Version(s)

8.0 for function/method deprecations, for class constants/properties and parameters maybe 8.1

RFC Impact

To SAPIs

None

To Existing Extensions

None

To Opcache

None

New Constants

None

php.ini Defaults

None

Open Issues

Is there an efficient way to check for Deprecated properties and constants only when they are declared on a class and otherwise keep the execution path unchanged? This will be a necessary requirement for deprecations on class constants and property deprecations. Otherwise this feature would have too much overhead.

Proposed Voting Choices

Accept <<Deprecated>> attribute into core?

Patches and Tests

https://github.com/beberlei/php-src/pull/11

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

rfc/deprecated_attribute.txt · Last modified: 2020/05/06 14:02 by beberlei