PHP 8: Attributes - Understanding and Implementing Metadata in Modern PHP
Dive deep into PHP 8 Attributes: Learn how to use this powerful feature for adding metadata to classes and methods. Real-world examples in Symfony, understand the differences from annotations.
What are PHP Attributes?
PHP attributes, introduced in PHP 8 let you add metadata to classes or methods. In the Symfony framework, they are widely adopted for configuration purposes.
How to Use Attributes?
Attributes in PHP are defined using the #[Attribute]
syntax. Take a look at this example, where validation constraints are defined for a Symfony entity class:
use Symfony\Component\Validator\Constraints as Assert;
class User
{
#[Assert\NotBlank]
private string $name;
#[Assert\Email]
private string $email;
}
In this example, #[Assert\NotBlank]
and #[Assert\Email]
are attributes used to add validation constraints directly to the properties of the User class.
What's the Difference Between Attributes and Annotations?
Annotations was a way to add metadata in PHP comments. That wasn't a part of the language though. More a convention. Previously, with annotations, this example would look like this:
use Symfony\Component\Validator\Constraints as Assert;
class User
{
/**
* @Assert\NotBlank
*/
private string $name;
/**
* @Assert\Email
*/
private string $email;
}
Since attributes, there's no point to use annotations anymore.
Routing Example in Symfony
Symfony makes heavy use of attributes. Here's a routing example:
class DefaultController extends AbstractController
{
#[Route('/home', name: 'home')]
public function home() {}
}
In that case, Symfony knows that for the /home
URL, it needs to run the home()
action from the DefaultController
.
How Can I Use Attributes in My Code?
Consider this example, which would let you iterate over all class-level attributes define for an example User
class:
$reflectionClass = new \ReflectionClass(User::class);
$attributes = $reflectionClass->getAttributes();
foreach ($attributes as $attribute) {
$instance = $attribute->newInstance();
}
Currently, attributes are mostly used by framework/library authors. They make much more sense there.
The most important thing is to understand the syntax and just beaware of their purpose. Which is, to add some metadata to classes or methods. That's all.