patternphplaravelTip
PHP 8.0 Attributes: Replacing DocBlock Annotations
Viewed 0 times
PHP 8.0+
attributeannotationreflectionphp 8.0#[Attribute]metadatadocblock replacement
Problem
PHP frameworks historically used DocBlock annotations (/** @Route('/path') */) for metadata. These are plain strings—not parsed by PHP, not type-checked, and break with minification or removal of comments.
Solution
Use PHP 8.0 native Attributes (#[AttributeClass]) for structured metadata on classes, methods, properties, and parameters. Define attribute classes with #[Attribute] and read them at runtime via Reflection API. Frameworks like Symfony and Laravel increasingly support attributes for routes, validation rules, and casts.
Why
Native attributes are parsed by PHP itself, are type-safe, support arguments, and survive comment stripping. They replace fragile string-based annotation parsing and enable IDE autocompletion.
Gotchas
- Attributes are not evaluated at declaration time—they must be read via Reflection to take effect
- An attribute class must be declared with #[Attribute] itself and can restrict targets via Attribute::TARGET_METHOD etc.
- Attribute arguments must be constant expressions—no variables or function calls
- Attribute instances are created on-demand by Reflection; constructors are called when getAttribute() is called
Code Snippets
Defining and reading a custom attribute
#[Attribute(Attribute::TARGET_METHOD)]
class Route
{
public function __construct(
public readonly string $path,
public readonly string $method = 'GET',
) {}
}
class PostController
{
#[Route('/posts', 'GET')]
public function index(): void {}
}
// Reading at runtime
$ref = new ReflectionMethod(PostController::class, 'index');
$attr = $ref->getAttributes(Route::class)[0]->newInstance();
echo $attr->path; // '/posts'Revisions (0)
No revisions yet.