Skip to content
Attributes (PHP 8+)
step 1/4

Reading — step 1 of 4

Learn

~1 min readReflection and Attributes

PHP 8 added native attributes — metadata you can attach to classes, methods, properties, parameters, then read via reflection.

<?php
#[Attribute(Attribute::TARGET_METHOD)]
class Route {
    public function __construct(
        public readonly string $path,
        public readonly string $method = 'GET',
    ) {}
}

class UserController {
    #[Route(path: '/users', method: 'GET')]
    public function list() { ... }

    #[Route(path: '/users/{id}', method: 'GET')]
    public function show(int $id) { ... }

    #[Route(path: '/users', method: 'POST')]
    public function create() { ... }
}

Reading attributes:

$rc = new ReflectionClass(UserController::class);
foreach ($rc->getMethods() as $method) {
    foreach ($method->getAttributes(Route::class) as $attr) {
        $route = $attr->newInstance();        // instantiates the Route
        echo "{$route->method} {$route->path} -> {$method->getName()}\n";
    }
}

Note: attributes are PHP classes annotated with #[Attribute]. They're inert until you explicitly read them via reflection.

Attribute::TARGET_* flags:

  • TARGET_CLASS, TARGET_METHOD, TARGET_PROPERTY, TARGET_PARAMETER, TARGET_FUNCTION, TARGET_CLASS_CONSTANT, TARGET_ALL
  • Combine with |: Attribute::TARGET_METHOD | Attribute::TARGET_FUNCTION
  • Attribute::IS_REPEATABLE — allow multiple of the same attribute

Use cases:

  • Routing (Symfony, Laravel route attributes)
  • Validation (#[Required], #[Min(0)], #[Email])
  • ORM mapping (#[Column(type: 'string')], #[Index])
  • Authorization (#[RequiresRole('admin')])
  • Test discovery (#[Test] for PHPUnit-like frameworks)

Before PHP 8, frameworks used doc-comments (/** @Route("/users") */) parsed via libraries like Doctrine Annotations. Native attributes are a big upgrade — language-level support, IDE-autocomplete, type-checked.

Modern PHP framework code (Symfony 6+, Laravel 9+) leans heavily on attributes for declarative APIs.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…