A while ago, I shared one possible approach to ignore a filter for one policy method. In that tip, I mentioned using a PHP attribute, and I got several follow-up questions from devs about how attributes work.
Since this is a relatively new PHP language feature, I thought it would be worth going a little bit deeper on the concept of attributes in general.
Starting in PHP 8, the language has a built-in Attribute
class that you can use to define your own attributes.
Continuing the example from the original tip, the definition for my EnforceForAllUsers
attribute looks like this:
declare(strict_types=1);
namespace App\Attributes;
use Attribute;
#[Attribute]
class EnforceForAllUsers {}
That's the whole file. I just create a plain old class, name it whatever I want, and decorate it with the #[Attribute]
attribute.
I'm not extending anything. There's no logic inside it. It's a very basic class.
I can then use this new attribute to decorate other classes (or methods, properties, and so on) in my application.
You can get more granular and enforce where your attribute could be used.
In my example, I probably would not want a whole policy class to be decorated with this attribute, only individual methods. I could do that like this:
declare(strict_types=1);
namespace App\Attributes;
use Attribute;
#[Attribute(Attribute::TARGET_METHOD)]
class EnforceForAllUsers {}
But the basic concept remains the same. An attribute is just a label you can apply to your code to give it some extra meaning.
Even if you never write your own attribute, they're becoming more common in Laravel, Livewire, and Composer packages, so it's good to understand how they work.
Here to help,
Joel
P.S. Laracon is over! Come join the Mastering Laravel community and talk about your favorite new releases.