PHP 8 attributes, what's new?

PHP 8 is a promising release. Among all new features and breaking changes, there’s a special feature called attributes that deserves, IMHO, at least one post.

Disclaimer

I want to focus on the usefulness of attributes. I will give examples and stuff, but this won’t be exhaustive.

Where does it come from?

Attributes are available in various languages such as Java, C#, C++, or Rust.

In PHP, it exists too but in an unstructured form as a pseudo-language, and PHP developers use it very often.

If you are familiar with Symfony, you probably already use something called Annotations, which is an additional layer that parses doc-comments to build mappings and configurations.

Annotations are excellent, but the final RFC likes to go further by including the feature in the language itself and extend its use to more elements.

Don’t be afraid:

Symfony 5.2 will include support for PHP 8 attributes to define routes and required dependencies. If you already use annotations, the transition will be seamless.

Source

What are attributes?

They are structured metadata. To write a class attribute, for example, you will do something like that:

#[Attribute] 
class MyClass {
}

The idea is to associate mappings and configurations in code directly and to be able to fetch them elsewhere in the code easily.

Metadata for what?

We write metadata to fetch them elsewhere in the code, for example, to check properties of elements. The Reflection classes are perfect candidates for that.

You will be able to use the new getAttributes() method from the ReflectionClass to validate things:

$reflected = new ReflectionClass(MyClass::class);
foreach ($reflected->getAttributes() as $attr) {
    print_r($attr->newInstance());
} 

PHP 8 evaluates attributes at runtime, which is cool for validating things (the later, the better).

Besides, all Reflection classes will have the getAttributes() method.

Attributes everywhere/somewhere

By default, you will be able to use element’s attributes everywhere for any element, but you will also be able to change that:

#[Attribute(Attribute::TARGET_METHOD)]
class MyClass {
}

The above code specifies you can only use the attribute in a method. Usage in any other element will trigger an error in this case.

Wrap up

I hope you liked this short introduction to PHP 8 attributes. Hopefully, developers will use this robust syntax extensively.

It’s pretty cool to have this new syntax that can be parsed by both the PHP engine and developers through the Reflection API.

I’m sure IDE’s are already implementing php 8 attributes to provide crazy useful autocompletion and other fancy tools.