rfc:simple-annotations

This is an old revision of the document!


PHP RFC: Simple Annotations

Introduction

This RFC proposes the introduction of simple value annotations - arbitrary meta-data values applicable to classes and class members, obtainable via the reflection API.

As an alternative proposal to attributes, this proposal aims to fully leverage existing language features, in order to provide more flexibility, lessen the learning curve, and expose meta-data in a manner that is more immediately useful, without having to build any run-time facilities.

Compared with annotation systems such as Doctrine Annotations, this proposal does not attempt to define or enforce any domain rules - it does not define inheritance semantics, rules about applicable source-code elements, cardinality, or any other rules; these can be defined and implemented by userland packages.

Proposal

The proposed syntax of a single annotation is extremely simple:

"<<" <php-expression> ">>"

Any valid PHP expression is a valid annotation.

Any number of annotations may be placed in front of any of the following applicable declarations:

  • class, trait and interface declarations
  • function and property declarations in classes/traits/interfaces
  • function and method argument declarations
  • anonymous function and class declarations (and their members)

Annotations are internally collected, for each annotated class or member, in a list which can be obtained via reflection.

The following trivial example annotates a class with a string and an array of numbers:

<< "Hello World" >>
<< [1, 2, 3] >>
class Hello
{}

The following example annotates an entity with a TableName instance, which might be consumed by a database abstraction:

class TableName
{
    public $name;
 
    public function __construct($name) {
        $this->name = $name;
    }
}
 
<< new TableName("users") >>
class User
{
    // ...
}
 
$reflection = new ReflectionClass(User::class);
 
var_dump($reflection->getAnnotations());

Example output:

array(1) {
  [0]=>
  object(TableName)#1 (1) {
    ["name"]=>
    string(5) "users"
  }
}

Annotation expressions are not evaluated until reflection is invoked, and are evaluated only once and internally memoized upon the first call to getAnnotations().

Context Free

Annotations are context-free - there is no access to variables in the parent class, file or global scope, no self or static or $this.

This is by design - annotations work consistently regardless of which source element they are applied to, and may be evaluated without first creating an object instance.

Annotations that do require context should explicitly ask for that context - for example, you could use an anonymous function to provide context via dependency injection.

Backward Incompatible Changes

None.

Proposed PHP Version(s)

Next PHP 7.x.

RFC Impact

To SAPIs

TODO

To Existing Extensions

TODO

To Opcache

TODO

Open Issues

Make sure there are no open issues when the vote starts!

Unaffected PHP Functionality

Annotations are a new feature - it does not affect any existing functionality.

Future Scope

TODO file-level annotations? others?

Proposed Voting Choices

TODO State whether this project requires a 2/3 or 50%+1 majority (see voting)

Patches and Tests

There is a draft with no available implementation at this time.

Implementation

TODO After the project is implemented, this section should contain

  1. the version(s) it was merged to
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature

References

Rejected Features

None.

rfc/simple-annotations.1463133870.txt.gz · Last modified: 2017/09/22 13:28 (external edit)