====== PHP RFC: Attributes on Constants ======
* Version: 0.2
* Date: 2024-11-30
* Author: Daniel Scherzer, daniel.e.scherzer@gmail.com
* Status: Under Discussion
* First Published at: http://wiki.php.net/rfc/attributes-on-constants
* Implementation: https://github.com/php/php-src/pull/16952
===== Introduction =====
Attributes were first introduced in [[rfc:attributes_v2]], with the current syntax adopted [[rfc:shorter_attribute_syntax_change]]. This RFC would add support for attributes on
* Compile-time non-class constants
To the list of current valid targets (see [[rfc:attributes_v2#attribute_syntax]]):
* functions (including closures and short closures)
* classes (including anonymous classes), interfaces, traits
* class constants
* class properties
* class methods
* function/method parameters
Additionally, taking advantage of this new feature, the #[\Deprecated] attribute is updated to also target compile-time non-class constants.
"Compile-time non-class constants" refers to constants defined via const MY_CONST = 5; (for example) rather than those via define( 'MY_CONST', 5 );. Unless clear from context, in this RFC "constant" refers to a compile-time non-class constant.
===== Proposal =====
Attributes are allowed to target constants, with the introduction of a Attribute::TARGET_CONSTANT. Additionally, Attribute::TARGET_ALL will now include constants.
To prevent confusing code, attributes are only allowed to be applied to constants that are declared in their own statement:
// This is okay
#[\MyAttribute]
const Example1 = 1;
// This is an error
#[\MyAttribute]
const Example2 = 2,
Example3 = 3;
To expose information about these attributes to runtime, ReflectionConstant::getAttributes() is introduced.
Additionally, the #[\Deprecated] attribute is updated to allow targeting constants; when applied, the constant is marked with ''CONST_DEPRECATED''.
===== Backward Incompatible Changes =====
Given that Attribute is final, the added constant shouldn't cause any conflicts. Likewise, ReflectionConstant is final, so the added method shouldn't cause any conflicts.
Existing attributes that use Attribute::TARGET_ALL may need to be updated if they do not apply to constants.
Furthermore, as with all RFCs that make code that previously had a compile-time error become valid, this RFC requires updates to static analyzers and IDEs to understand the semantics of adding attributes to constants and not erroneously report errors.
===== Proposed PHP Version(s) =====
Next version of PHP (PHP 8.5 or PHP 9.0)
===== RFC Impact =====
==== To SAPIs ====
Just noting for completion: the current implementation passes the attribute information to runtime via a new opcode, ''ZEND_DECLARE_ATTRIBUTED_CONST'', that phpdbg will ignore the same way it ignores ''ZEND_DECLARE_CONST''.
==== To Opcache ====
The JIT currently has logic to emit deprecation messages for constants that are deprecated; to avoid duplicating the new logic to check a constant's attributes for a #[\Deprecated] attribute, that logic is centralized in a new zend_deprecated_constant() function.
==== To Reflection ====
New method ReflectionConstant::getAttributes() is added, with a signature to match the other such methods for retrieving attributes:
final class ReflectionConstant implements Reflector
{
// Everything that currently exists
// ...
public function getAttributes(?string $name = null, int $flags = 0): array {}
}
Additionally, code that expects ReflectionConstant::isDeprecated() to always return false for userland constants will need to be updated, since it can now be true.
==== New Constants ====
Attribute::TARGET_CONSTANT indicates that an attribute can be applied to compile-time non-class constants.
===== Unaffected PHP Functionality =====
Existing uses of attributes or constants - previously, trying to add an attribute to a constant would have generated an error, so any existing working current code should continue to work as expected.
===== Future Scope =====
Adding support to non-compile-time non-class constants, via define().
===== Proposed Voting Choices =====
This vote requires a 2/3 majority to adopt.
===== Patches and Tests =====
https://github.com/php/php-src/pull/16952
===== Implementation =====
After the project is implemented, this section should contain
- the version(s) it was merged into
- a link to the git commit(s)
- a link to the PHP manual entry for the feature
- a link to the language specification section (if any)
===== References =====
* [[rfc:attributes_v2]]
* [[rfc:shorter_attribute_syntax_change]]
* https://github.com/php/php-src/pull/16952
===== Changelog =====
0.2:
* Improved discussion of backward incompatible changes