Building on yesterday's tip about PHP attributes, there's one more thing worth discussing.
How do you use attributes to influence behavior? As we saw, the attribute class is just an empty class, so how does it actually affect our application?
Because attributes are metadata, we need to use reflection to see if they are present on a given class, method, or property. And then we can act accordingly.
Reflection is a way to inspect code at runtime, and it is the only way to access attributes.
For reference, here's the code sample from the tip that started it this whole discussion:
#[EnforceForAllUsers]
public function showPublicLink(User $user, Show $show): bool { /* logic omitted */}
public function before(User $user, string $ability)
{
$policyMethod = new ReflectionMethod(self::class, $ability);
if ($policyMethod->getAttributes(EnforceForAllUsers::class)) {
return null;
}
if ($user->hasRole(Role::SUPER_ADMIN)) {
return true;
}
}
As you can see, my before
method is using reflection to see if the ability being called has the EnforceForAllUsers
attribute.
And if it does, it alters behavior by returning null
and bypassing this filter entirely.
Think of it like querying your code from your code.
Reflection has been around in PHP for a long time, and some developers have learned to avoid it for performance reasons.
As with many things, the performance has improved significantly over time with newer PHP releases.
In most typical web applications talking to a database, I think you'd be very hard-pressed to notice a performance hit from using reflection.
Here to help,
Joel
P.S. Are you still on a version of PHP that is no longer supported? We can help you plan a migration.