Attributes
| #[...] syntax | |
| Read them with reflection | |
| Built-in attributes | |
| When attributes pay off |
#[...] syntax
An attribute is structured metadata placed right above a class, method, property, or parameter.
It replaces doc comment annotations with syntax the engine understands. See also
attributes in PHP 8.0.
Start with a plain class for the attribute, then apply it with hash and brackets.
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)] class Route { public function __construct(public string $path) {} } #[Route("/api/users")] class UserController { }
Arguments follow normal call syntax, including named arguments and arrays. Applying an attribute never runs code by itself, it only stores metadata.
Read them with reflection
Reflection reads attributes at runtime. Ask a reflection object for its attributes,
filter by class name, then create an instance to get the stored values.
This pattern powers routers, validators, and test runners.
$ref = new ReflectionClass(UserController::class); foreach ($ref->getAttributes(Route::class) as $attr) { $route = $attr->newInstance(); echo $route->path; }
Built-in attributes
PHP ships a small set of engine attributes. They mark overrides, silence deprecations
during internal migrations, and hide sensitive values from stack traces.
Learn these four first, then check the manual for version specific additions.
class TokenStore { #[ReturnTypeWillChange] public function count(): int { return 0; } public function login( string $name, #[SensitiveParameter] string $password ): bool { return $name !== "" && $password !== ""; } }
Override checks that a method really overrides a parent method. Deprecated marks your own API as scheduled for removal.
When attributes pay off
Use attributes when one declaration must serve both code and configuration.
Routing, validation rules, serialization names, and access policies are classic cases.
Skip them for plain business logic. A normal method call is easier to debug than hidden metadata.
#[Route("/api/users")] function listUsers(): array { return []; } $fn = new ReflectionFunction("listUsers"); var_dump(count($fn->getAttributes()));
Next: Exceptions
Article author: Arthur Isaev