rfc:attributes-on-constants

This is an old revision of the document!


PHP RFC: Attributes on Constants

Introduction

Attributes were first introduced in attributes_v2, with the current syntax adopted 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 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

New constant Attribute::TARGET_CONSTANT may conflict with subclasses that define such a constant of their own.

Since ReflectionConstant is final, the added method shouldn't cause any conflicts.

Extensions that validate the usage of their attributes and use Attribute::TARGET_ALL may need to be updated.

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

Implementation

After the project is implemented, this section should contain

  1. the version(s) it was merged into
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature
  4. a link to the language specification section (if any)

References

rfc/attributes-on-constants.1732985454.txt.gz · Last modified: 2024/11/30 16:50 by danielescherzer