rfc:deprecated_attribute

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
rfc:deprecated_attribute [2020/12/18 22:47] beberleirfc:deprecated_attribute [2024/04/19 09:01] (current) timwolla
Line 1: Line 1:
-====== PHP RFC: #[Deprecated] Attribute ======+====== PHP RFC: #[\Deprecated] Attribute ======
  
-  * Version: 1.1 +  * Version: 1.3-dev 
-  * Date: 2020-05-06 +  * Date: 2024-04-15 
-  * Author: Benjamin Ebelei +  * Author: Benjamin Eberlei, Tim Düsterhus 
   * Status: Under Discussion   * Status: Under Discussion
   * First Published at: http://wiki.php.net/rfc/deprecated_attribute   * First Published at: http://wiki.php.net/rfc/deprecated_attribute
Line 9: Line 9:
 ===== Introduction ===== ===== Introduction =====
  
-With the Attributes RFC accepted for PHP 8, this is a first proposal for an internal attribute hooking into the engine.+With the Attributes RFC accepted for PHP 8, this is a 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 internal functions and methods 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. 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.
Line 15: Line 17:
 ===== Proposal ===== ===== Proposal =====
  
-<nowiki>Developers can put an attribute #[Deprecated] on the following elements:</nowiki>+<nowiki>Developers can put an attribute #[Deprecated] on the following elements (targets):</nowiki>
  
   * Functions   * Functions
   * Methods   * Methods
  
-It is not possible to target classes, constants, properties or arguments at the moment. This might be added in other RFCs later.+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.
  
-Using attribute will add "ZEND_ACC_DEPERACTED" function flag to the op_array, which will automatically (with only small changes to the VM) lead to a deprecation warning alreadysince this functionality is present for internal functions already. This attribute exposes a this deprecation feature for functions to userland and close a gap between internal and userland functions.+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 lead to a deprecation warning when the function is called at runtimewith only minimal changes in the VM. 
 + 
 +The ZEND_ACC_DEPRECATED flag and behavior is present for internal functions already. The presence of Deprecated attribute allows to expose this feature to userland functions/methods and closes capability gap between internal and userland functions. 
 + 
 +For userland functions the E_USER_DEPRECATED level is used, instead of the E_DEPRECATED that is raised for internal functions.
  
 <code php> <code php>
 <?php <?php
  
-<<Deprecated>>+use Deprecated
 + 
 +#[Deprecated]
 function test() {} function test() {}
 // Deprecated: Function test() is deprecated // Deprecated: Function test() is deprecated
  
-<<Deprecated("use test3() instead")>>+#[Deprecated("use test3() instead")]
 function test2() {} function test2() {}
 // Deprecated: Function test2() is deprecated, use test3() instead // Deprecated: Function test2() is deprecated, use test3() instead
  
 class Foo { class Foo {
-    <<Deprecated>>+    #[Deprecated]
     public function test() {}     public function test() {}
     // Deprecated: Method Foo::test() is deprecated in %s     // Deprecated: Method Foo::test() is deprecated in %s
 } }
 </code> </code>
 +
 +The deprecated class is final and cannot be extended. The reason for this is that the engine internally cannot autoload attributes, so checking for a subclass that extends the Deprecated class is not technically possible. Marking the class as final prevents that users extend the class and expect their children exhibit the same behavior.
 +
 +==== 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 PHP's 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.
 +
 +This feature adds a small bitmask check in the VM for every function call.
 +
 +Changes to the runtime warning stack of PHP are out of the scope of this RFC.
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
  
-class with the name "Deprecated" is introduced into the global namespace.+<php>Deprecated</php> can no longer be used as a class name in the global namespace. A GitHub search for ''"class Override " language:php symbol:override'' revealed a total of 318 matches in source code. Many of them appear within a comment. The actual class definition all appear to be defined within a namespace.
  
 ===== Proposed PHP Version(s) ===== ===== Proposed PHP Version(s) =====
  
-8.1 for function/method deprecations+Next minor (PHP 8.4).
  
 ===== RFC Impact ===== ===== RFC Impact =====
 +
 ==== To SAPIs ==== ==== To SAPIs ====
-None+ 
 +None.
  
 ==== To Existing Extensions ==== ==== To Existing Extensions ====
-None+ 
 +None.
  
 ==== To Opcache ==== ==== To Opcache ====
  
-None+None.
  
 ==== New Constants ==== ==== New Constants ====
  
-None+None.
  
 ==== php.ini Defaults ==== ==== php.ini Defaults ====
  
-None+None.
  
 ===== Open Issues ===== ===== Open Issues =====
  
-A few things tracked in https://github.com/php/php-src/pull/6521+A few things tracked in https://github.com/php/php-src/pull/11293 
 + 
 +===== Future Scope ===== 
 + 
 +  * Allowing #[\Deprecated] on classes or other targets of attributes 
 +  * Adding further metadata to the Deprecated attribute beyond a custom message, such as hints for replacements that IDEs could use.
  
 ===== Proposed Voting Choices ===== ===== Proposed Voting Choices =====
  
-Accept #[Deprecated] attribute into core?+<doodle title="Accept the #[\Deprecated] attribute as described?" auth="timwolla" voteType="single" closed="false" closeon="2022-01-01T00:00:00Z"> 
 +   * Yes 
 +   * No 
 +</doodle>
  
 ===== Patches and Tests ===== ===== Patches and Tests =====
  
-https://github.com/php/php-src/pull/6521+https://github.com/php/php-src/pull/11293 
 + 
 +===== Implementation ===== 
 + 
 +n/a 
 + 
 +===== References ===== 
 + 
 +  * Implementation: https://github.com/php/php-src/pull/11293 
 +  * Early Mailing List Discussion: https://externals.io/message/112554#112554 
 + 
 +===== Rejected Features =====
  
-No implementation for deprecated class constants, properties and parameters yet.+n/a
rfc/deprecated_attribute.1608331621.txt.gz · Last modified: 2020/12/18 22:47 by beberlei