rfc:attribute_amendments

PHP RFC: Attribute Amendments

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://wiki.php.net/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_REPEATABLE should 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

Should PhpAttribute be renamed to Attribute?
Real name Yes No
alcaeus Image 
alec Image 
asgrim Image 
ashnazg Image 
beberlei Image 
bmajdak Image 
brzuchal Image 
bwoebi Image 
carusogabriel Image 
colinodell Image 
cpriest Image 
danack Image 
daverandom Image 
derick Image 
galvao Image 
girgias Image 
heiglandreas Image 
jasny Image 
jbnahan Image 
jhdxr Image 
kalle Image 
kelunik Image 
kguest Image 
klaussilveira Image 
kocsismate Image 
marandall Image 
marcio Image 
mariano Image 
mbeccati Image 
mike Image 
nicolasgrekas Image 
nikic Image 
ocramius Image 
patrickallaert Image 
pierrick Image 
pmjones Image 
pollita Image 
ramsey Image 
reywob Image 
ruudboon Image 
santiagolizardo Image 
sebastian Image 
sergey Image 
sirsnyder Image 
stas Image 
svpernova09 Image 
tandre Image 
thekid Image 
theodorejb Image 
trowski Image 
zimt Image 
Final result: 51 0
This poll has been closed.

Group statement for Attributes

Should a secondary grouped syntax for attributes be introduced?
Real name Yes No
alcaeus Image 
alec  Image
asgrim Image 
ashnazg Image 
beberlei Image 
bmajdak Image 
brzuchal Image 
bwoebi Image 
cpriest Image 
danack  Image
daverandom Image 
derick  Image
galvao Image 
heiglandreas  Image
jasny  Image
jbnahan Image 
jhdxr  Image
kalle Image 
kelunik Image 
kguest Image 
klaussilveira Image 
kocsismate  Image
marandall Image 
marcio Image 
mariano Image 
mbeccati Image 
mike Image 
nicolasgrekas Image 
ocramius Image 
patrickallaert  Image
pierrick Image 
pollita Image 
ramsey Image 
rasmus  Image
reywob  Image
ruudboon Image 
santiagolizardo Image 
sebastian  Image
sergey Image 
sirsnyder Image 
stas  Image
svpernova09 Image 
thekid Image 
theodorejb  Image
trowski Image 
zimt  Image
Final result: 32 14
This poll has been closed.

Validate Attribute Target Declarations

Should attributes allow definition of target declarations?
Real name Yes No
alcaeus Image 
alec Image 
asgrim Image 
ashnazg Image 
beberlei Image 
bmajdak Image 
brzuchal Image 
bwoebi Image 
colinodell Image 
cpriest  Image
danack  Image
daverandom Image 
derick Image 
galvao Image 
jasny Image 
jbnahan Image 
jhdxr Image 
kalle Image 
kelunik Image 
kguest Image 
klaussilveira Image 
kocsismate Image 
marandall Image 
marcio Image 
mariano Image 
mbeccati Image 
mike Image 
nicolasgrekas Image 
ocramius Image 
pierrick Image 
pollita Image 
ramsey Image 
rasmus  Image
reywob Image 
ruudboon Image 
sebastian Image 
sergey Image 
sirsnyder Image 
stas  Image
svpernova09 Image 
tandre Image 
trowski Image 
Final result: 38 4
This poll has been closed.

Validate Attribute Repeatability

Should attributes allow definition of repeatability?
Real name Yes No
alcaeus  Image
alec Image 
asgrim Image 
ashnazg Image 
beberlei Image 
bmajdak Image 
brzuchal Image 
bwoebi Image 
cpriest Image 
danack  Image
daverandom Image 
derick Image 
galvao Image 
jasny  Image
jbnahan Image 
jhdxr Image 
kalle Image 
kelunik Image 
kguest Image 
klaussilveira Image 
kocsismate Image 
marandall Image 
marcio Image 
mariano Image 
mbeccati Image 
mike Image 
nicolasgrekas Image 
ocramius Image 
patrickallaert Image 
pierrick Image 
pollita Image 
ramsey Image 
reywob Image 
ruudboon Image 
santiagolizardo Image 
sebastian Image 
sergey Image 
sirsnyder Image 
stas  Image
svpernova09 Image 
tandre Image 
trowski Image 
Final result: 38 4
This poll has been closed.

Patches and Tests

References

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)
rfc/attribute_amendments.txt · Last modified: by 127.0.0.1

Image