Take the State of PHP 2026 Survey →

Attribute Amendments View as Markdown

Implemented (PHP 8.0)
Authors
Benjamin Eberlei (beberlei@php.net), Martin Schröder
Date
2020-05-11
Version
1.2
Target
8.0
Source
wiki.php.net/rfc/attribute_amendments

Votes

Should PhpAttribute be renamed to Attribute? closed
Yes
51
No
0
51 voters
alcaeus Yes 2020-06-09 09:08
alec Yes 2020-06-08 10:57
asgrim Yes 2020-06-08 08:25
ashnazg Yes 2020-06-17 15:39
beberlei Yes 2020-06-08 08:12
bmajdak Yes 2020-06-08 21:55
brzuchal Yes 2020-06-08 08:54
bwoebi Yes 2020-06-08 08:56
carusogabriel Yes 2020-06-18 09:21
colinodell Yes 2020-06-08 14:14
cpriest Yes 2020-06-20 21:08
danack Yes 2020-06-08 08:50
daverandom Yes 2020-06-09 17:07
derick Yes 2020-06-08 09:32
galvao Yes 2020-06-10 09:09
girgias Yes 2020-06-08 10:31
heiglandreas Yes 2020-06-13 14:59
jasny Yes 2020-06-08 10:00
jbnahan Yes 2020-06-22 11:46
jhdxr Yes 2020-06-10 17:51
kalle Yes 2020-06-08 09:39
kelunik Yes 2020-06-21 19:51
kguest Yes 2020-06-17 14:06
klaussilveira Yes 2020-06-16 18:24
kocsismate Yes 2020-06-08 08:18
marandall Yes 2020-06-08 15:35
marcio Yes 2020-06-16 06:18
mariano Yes 2020-06-08 10:39
mbeccati Yes 2020-06-09 10:41
mike Yes 2020-06-08 11:43
nicolasgrekas Yes 2020-06-08 08:49
nikic Yes 2020-06-08 09:33
ocramius Yes 2020-06-08 08:41
patrickallaert Yes 2020-06-16 10:10
pierrick Yes 2020-06-15 14:00
pmjones Yes 2020-06-08 12:14
pollita Yes 2020-06-14 16:46
ramsey Yes 2020-06-08 16:54
reywob Yes 2020-06-08 08:52
ruudboon Yes 2020-06-11 15:20
santiagolizardo Yes 2020-06-15 17:40
sebastian Yes 2020-06-08 12:09
sergey Yes 2020-06-15 06:52
sirsnyder Yes 2020-06-15 22:43
stas Yes 2020-06-08 19:12
svpernova09 Yes 2020-06-18 14:22
tandre Yes 2020-06-19 13:58
thekid Yes 2020-06-14 10:18
theodorejb Yes 2020-06-19 13:48
trowski Yes 2020-06-08 14:19
zimt Yes 2020-06-11 13:05
Should a secondary grouped syntax for attributes be introduced? closed
Yes
32
No
14
46 voters
alcaeus Yes 2020-06-09 09:08
alec No 2020-06-08 10:57
asgrim Yes 2020-06-08 08:25
ashnazg Yes 2020-06-17 15:40
beberlei Yes 2020-06-08 08:13
bmajdak Yes 2020-06-08 21:56
brzuchal Yes 2020-06-08 08:55
bwoebi Yes 2020-06-08 08:57
cpriest Yes 2020-06-20 21:11
danack No 2020-06-08 08:54
daverandom Yes 2020-06-09 17:07
derick No 2020-06-08 09:33
galvao Yes 2020-06-10 09:12
heiglandreas No 2020-06-13 15:00
jasny No 2020-06-08 10:00
jbnahan Yes 2020-06-22 11:46
jhdxr No 2020-06-10 17:52
kalle Yes 2020-06-08 09:43
kelunik Yes 2020-06-21 19:52
kguest Yes 2020-06-17 14:07
klaussilveira Yes 2020-06-16 18:24
kocsismate No 2020-06-08 08:20
marandall Yes 2020-06-08 15:36
marcio Yes 2020-06-16 06:18
mariano Yes 2020-06-08 10:39
mbeccati Yes 2020-06-09 10:42
mike Yes 2020-06-08 11:43
nicolasgrekas Yes 2020-06-08 08:49
ocramius Yes 2020-06-08 08:40
patrickallaert No 2020-06-16 10:11
pierrick Yes 2020-06-15 14:01
pollita Yes 2020-06-14 16:46
ramsey Yes 2020-06-08 16:54
rasmus No 2020-06-12 21:31
reywob No 2020-06-08 08:53
ruudboon Yes 2020-06-11 15:21
santiagolizardo Yes 2020-06-15 17:41
sebastian No 2020-06-08 12:11
sergey Yes 2020-06-15 06:53
sirsnyder Yes 2020-06-15 22:43
stas No 2020-06-08 19:13
svpernova09 Yes 2020-06-18 14:22
thekid Yes 2020-06-14 10:17
theodorejb No 2020-06-19 13:47
trowski Yes 2020-06-08 14:20
zimt No 2020-06-11 13:05
Should attributes allow definition of target declarations? closed
Yes
38
No
4
42 voters
alcaeus Yes 2020-06-09 09:08
alec Yes 2020-06-08 10:57
asgrim Yes 2020-06-08 08:25
ashnazg Yes 2020-06-17 15:41
beberlei Yes 2020-06-08 08:13
bmajdak Yes 2020-06-08 21:56
brzuchal Yes 2020-06-08 08:55
bwoebi Yes 2020-06-08 08:57
colinodell Yes 2020-06-08 14:14
cpriest No 2020-06-20 21:11
danack No 2020-06-08 08:53
daverandom Yes 2020-06-09 17:07
derick Yes 2020-06-08 09:33
galvao Yes 2020-06-10 09:12
jasny Yes 2020-06-08 10:01
jbnahan Yes 2020-06-22 11:48
jhdxr Yes 2020-06-10 17:52
kalle Yes 2020-06-08 09:42
kelunik Yes 2020-06-21 19:52
kguest Yes 2020-06-17 14:07
klaussilveira Yes 2020-06-16 18:24
kocsismate Yes 2020-06-08 08:19
marandall Yes 2020-06-08 15:35
marcio Yes 2020-06-14 04:00
mariano Yes 2020-06-08 10:40
mbeccati Yes 2020-06-09 10:42
mike Yes 2020-06-08 11:44
nicolasgrekas Yes 2020-06-08 08:49
ocramius Yes 2020-06-08 08:37
pierrick Yes 2020-06-15 14:02
pollita Yes 2020-06-14 16:46
ramsey Yes 2020-06-08 16:54
rasmus No 2020-06-12 21:31
reywob Yes 2020-06-08 08:53
ruudboon Yes 2020-06-11 15:21
sebastian Yes 2020-06-08 12:10
sergey Yes 2020-06-15 06:53
sirsnyder Yes 2020-06-15 22:43
stas No 2020-06-08 19:13
svpernova09 Yes 2020-06-18 14:22
tandre Yes 2020-06-19 13:58
trowski Yes 2020-06-08 14:20
Should attributes allow definition of repeatability? closed
Yes
38
No
4
42 voters
alcaeus No 2020-06-09 09:10
alec Yes 2020-06-08 10:58
asgrim Yes 2020-06-08 08:26
ashnazg Yes 2020-06-17 15:41
beberlei Yes 2020-06-08 08:37
bmajdak Yes 2020-06-08 21:56
brzuchal Yes 2020-06-08 08:55
bwoebi Yes 2020-06-08 08:57
cpriest Yes 2020-06-20 21:11
danack No 2020-06-08 08:53
daverandom Yes 2020-06-09 17:06
derick Yes 2020-06-08 09:33
galvao Yes 2020-06-10 09:13
jasny No 2020-06-08 10:03
jbnahan Yes 2020-06-22 11:48
jhdxr Yes 2020-06-10 17:53
kalle Yes 2020-06-08 09:42
kelunik Yes 2020-06-21 19:52
kguest Yes 2020-06-17 14:08
klaussilveira Yes 2020-06-16 18:24
kocsismate Yes 2020-06-08 08:46
marandall Yes 2020-06-08 15:35
marcio Yes 2020-06-16 06:18
mariano Yes 2020-06-08 10:40
mbeccati Yes 2020-06-09 10:42
mike Yes 2020-06-08 11:44
nicolasgrekas Yes 2020-06-08 08:49
ocramius Yes 2020-06-08 08:41
patrickallaert Yes 2020-06-16 10:13
pierrick Yes 2020-06-15 14:02
pollita Yes 2020-06-14 16:46
ramsey Yes 2020-06-08 16:55
reywob Yes 2020-06-08 08:53
ruudboon Yes 2020-06-11 15:21
santiagolizardo Yes 2020-06-15 17:42
sebastian Yes 2020-06-08 12:10
sergey Yes 2020-06-15 06:53
sirsnyder Yes 2020-06-15 22:44
stas No 2020-06-08 19:13
svpernova09 Yes 2020-06-18 14:22
tandre Yes 2020-06-19 13:58
trowski Yes 2020-06-08 14:21

Discussions on the mailing list

[RFC] Amendments to Attributes
by Benjamin Eberlei · 30 messages
[VOTE] Attribute Amendments
by Benjamin Eberlei · 14 messages
Typed constants
by Benas IML · 3 messages

RFC text

Copied from wiki.php.net, last synchronized Oct 13, 2026 11:51 UTC

Introduction

This RFC discusses a few amendments to the original Attributes RFC that was accepted for PHP 8.

Rename PhpAttribute class to Attribute

Important Context: Since the acceptence of Attributes, the PhpCompilerAttribute and PhpAttribute classes were unified to be only PhpAttribute. This was needed because the previous approach of disallowing the use of <<PhpCompilerAttribute>> in userland would break "stub" generation that static analysis and IDEs rely on to fill their type database of internal functions/classes. Without it there was no functionality left in PhpCompilerAttribute to preserve.

The original RFC introduced a PhpAttribute class to be added to new userland attributes. This name was inspired by PhpToken and to potentially avoid breaking existing userland codebases with a class called Attribute. However the Php prefix makes no sense for the attribute class compared to PhpToken.

In absence of a namespace policy, the global namespace is PHPs namespace. The documentation states as much and the vote on https://externals.io/rfc/php-namespace-in-core confirmed this.

Therefore we propose to rename PhpAttribute to be just Attribute and in addition recommend that all internal/compiler attributes should be placed under the global namespace as well.

Extensions providing non-core attributes should consider using their own namespace, but this RFC makes no recommendation or rule about this.

Group statement for Attributes

Right now each attribute requires to be surrounded by the T_SL/T_SR tokens:

<<Attr1>><<Attr2>>
class Example
{
    <<Attr2("foo")>>
    <<Attr2("bar")>>
    public function test()
    {
    }
}

We propose to allow a second syntax/style to group attributes in one declaration:

<<Attr1, Attr2>>
class Example
{
    <<Attr2("foo"),
      Attr2("bar")>>
    public function test()
    {
    }
}

In line with many other recent RFCs, trailing commas will also be possible in an attribute group declarations:

    <<
      Attr1("foo"),
      Attr2("bar"),
    >>
    public function test()
    {
    }

This feature would be superseded by any other RFC getting accepted that changes the syntax.

Validate Attribute Target Declarations

At the moment an attribute can be put on any kind of declaration and the developer of the attribute has no way of restricting the usage to only a subset of declarations. This functionality is only available to internal attributes for now.

As an example, a developer might introduce an attribute to declare what database table a class is stored in:

use ORM\Attributes\Table;
 
<<Table("users")>>
class User
{
}

But they cannot prevent the Table attribute being used on another declaration where it semantically does not belong:

use ORM\Attributes\Table;
 
class User
{
    <<Table("users")>>
    public $id;
}

We propose that you can optionally restrict the declarations an attribute can be used on by setting an optional argument to PhpAttribute (or Attribute).

namespace ORM\Attributes;
 
<<PhpAttribute(PhpAttribute::TARGET_CLASS)>>
class Table
{
}

The following constants will be added to PhpAttribute:

class PhpAttribute
{
    public const int TARGET_CLASS = 1;
    public const int TARGET_FUNCTION = (1 << 1);
    public const int TARGET_METHOD = (1 << 2);
    public const int TARGET_PROPERTY = (1 << 3);
    public const int TARGET_CLASS_CONSTANT = (1 << 4);
    public const int TARGET_PARAMETER = (1 << 5);
    public const int TARGET_ALL = ((1 << 6) - 1);
 
    public function __construct(int $flags = self::TARGET_ALL)
    {
    }
}

Important note: The target definition of an attribute is validated during the call to ReflectionAttribute::newInstance. In fact it does not influence a call to Reflection*::getAttributes() and ReflectionAttribute instances can be returned from this method, that are not valid on the reflected declaration. This is in line with the deferred validation of userland attributes that the original RFC championed.

Validate Attribute Repeatability

At the moment every attribute can be repeated multiple times on a declaration. For many use cases of attributes this is not desired.

For this reason we propose that by default attributes are not repeatable, and only if the PhpAttribute has the flag IS_REPEATABLEshould it be possible to use it multiple times on the same declaration:

class PhpAttribute
{
    public const int IS_REPEATABLE = ((1 << 10));
}
 
<<PhpAttribute(self::IS_REPEATABLE)>>
class Route
{
}
 
class HomepageController
{
    <<Route("/")>>
    <<Route("/homepage")>>
    public function indexAction()
    {
    }
}

Important note: The repeatable flag of an attribute is validated during the call to ReflectionAttribute::newInstance. In fact it does not influence a call to Reflection*::getAttributes() and ReflectionAttribute instances can be returned from this method, that are not valid on the reflected declaration. This is in line with the deferred validation of userland attributes that the original RFC championed.

Backward Incompatible Changes

Introducing a class Attribute into the global namespace is certainly going to break at least a handful of applications using this class name.

Proposed PHP Version(s)

8.0

RFC Impact

To SAPIs

none

To Existing Extensions

none

To Opcache

none

Open Issues

none

Vote

Voting will end on June 22nd, 2020 - 8:00 UTC.

Rename PhpAttribute class to Attribute

Vote: Should PhpAttribute be renamed to Attribute? — Yes: 51 · No: 0 (closed)

Group statement for Attributes

Vote: Should a secondary grouped syntax for attributes be introduced? — Yes: 32 · No: 14 (closed)

Validate Attribute Target Declarations

Vote: Should attributes allow definition of target declarations? — Yes: 38 · No: 4 (closed)

Validate Attribute Repeatability

Vote: Should attributes allow definition of repeatability? — Yes: 38 · No: 4 (closed)

Patches and Tests

  1. https://github.com/php/php-src/pull/5751

References

  1. Attributes RFC

Updates

  1. 1.0 Initial RFC (11.5.2020)
  2. 1.1 Attributes\Attribute namespace (28.5.2020)
  3. 1.2 Revert Attributes\Attribute namespace, make IS_REPEATABLE flag on PhpAttribute (4.6.2020)