DEV Community

Nacho Colomina Torregrosa
Nacho Colomina Torregrosa

Posted on

Using PHP attributes easily

PHP attributes are a new feature included in the last php 8 version which allow us to easily add metadata to our classes, methods and properties.

Creating an attribute is easy, we only have to create a class, define its properties and mark it as attribute. Let's see an example


    #[\Attribute]
    class IsBackground
    {
        public function __construct(
            public readonly ?int $delay = null
        ){ }
     }

Enter fullscreen mode Exit fullscreen mode

In the above code, we've created an attribute called IsBackground which holds one parameter: delay.

Now let's see how we could use it. Imagine we have a class called Operation which we want to decorate as "IsBackground".


    #[IsBackground]
    class Operation {

        // properties and methods
    }

Enter fullscreen mode Exit fullscreen mode

As we can see, it's already marked simply using #[IsBackground] at the top of the class.

Now, let's see how to read attribute data:

     $reflectionClass = new \ReflectionClass(new Operation());
     $attributes = $reflectionClass->getAttributes(IsBackground::class);
     $attr = reset($attributes);
     $attrObject = $attr->newInstance();

     echo $attr->delay;
Enter fullscreen mode Exit fullscreen mode

When we decorated Operation with IsBackground attribute we defined no delay. In order to set a delay, we would change Operation class like this:

#[IsBackground(delay: 600)]
class Operation {

    // properties and methods
}
Enter fullscreen mode Exit fullscreen mode

Top comments (5)

Collapse
 
osteel profile image
Yannick Chenot

Thanks for the simple example. Now, what would be the advantage of doing this over, say, a Background interface with a public getDelay() method, for instance?

Collapse
 
icolomina profile image
Nacho Colomina Torregrosa

Hi Yannick, Thanks to you too.

You can use attributes when you want to add metadata to a class but it is not necessary the class to follow a contract. If the class has to follow a contract then you would have to use an interface. Let's think about symfony messenger handlers. At the first versions handlers needed to implement MessageHandlerInterface but that interface did not hold any method. Now, to define a message handler you use_ #[AsMessageHandler] _attribute

Collapse
 
cbid2 profile image
Christine Belzie

Hi @icolomina. Welcome to Dev! It’s nice to meet you. I’m not familiar with phps but the way you explained the first code snippet made it a bit easier to understand. Keep it up! :)

Collapse
 
icolomina profile image
Nacho Colomina Torregrosa

Many thanks Christine! It's nice to write here :)

Collapse
 
hoshimxon profile image
Hoshimxon

I think last line should be echo $attrObject->delay; not echo $attr->delay;