{
    "slug": "attributes",
    "term": "Attributes / Annotations (PHP 8.0)",
    "category": "php",
    "difficulty": "intermediate",
    "short": "Native structured metadata attached to classes, methods, properties, and parameters using #[AttributeName] syntax.",
    "long": "PHP 8.0 attributes replace docblock-based annotations (used by PHPDoc, Doctrine, Symfony) with a first-class language feature. Attributes are declared with #[Attribute] on a class and applied with #[MyAttribute(args)] to target declarations. They are read at runtime via the Reflection API, making them suitable for routing, validation, serialisation, ORM mappings, and dependency injection metadata. Unlike docblocks, attributes are parsed by PHP itself, so syntax errors are caught at compile time.",
    "aliases": [
        "PHP attributes",
        "#[Attribute]",
        "PHP 8 annotations"
    ],
    "tags": [
        "php8",
        "php",
        "metadata",
        "reflection"
    ],
    "misconception": "PHP attributes are processed at runtime like docblock annotations. Attributes are resolved lazily via Reflection — they have zero runtime cost unless explicitly read. Docblock annotations require string parsing every time; attributes are part of the compiled opcode.",
    "why_it_matters": "PHP 8 Attributes provide native structured metadata on classes, methods, and properties — replacing docblock annotations with something that is parseable, type-safe, and IDE-verifiable.",
    "common_mistakes": [
        "Defining an Attribute class without #[Attribute] itself — the class is not recognised as an attribute.",
        "Not specifying the Attribute target flags — an attribute intended only for methods can accidentally be applied to classes.",
        "Accessing attribute data with manual regex parsing of docblocks instead of using ReflectionClass->getAttributes().",
        "Using attributes for runtime behaviour without understanding they require Reflection to read — they add no runtime behaviour themselves."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "constructor_promotion",
        "interfaces"
    ],
    "prerequisites": [
        "reflection_api",
        "type_declarations",
        "enums"
    ],
    "refs": [
        "https://www.php.net/manual/en/language.attributes.php"
    ],
    "bad_code": "// Attribute class missing the #[Attribute] marker:\nclass Route { // Not recognised as an attribute\n    public function __construct(public string $path) {}\n}\n\n#[Route('/users')] // Silent no-op\nclass UserController {}",
    "good_code": "// Define a custom attribute\n#[Attribute(Attribute::TARGET_METHOD)]\nclass Route {\n    public function __construct(\n        public readonly string $path,\n        public readonly string $method = 'GET',\n    ) {}\n}\n\n// Apply it\nclass UserController {\n    #[Route('/users', 'GET')]\n    public function index(): array { return []; }\n\n    #[Route('/users', 'POST')]\n    public function store(array $data): User { ... }\n}\n\n// Read it via Reflection\n$ref   = new ReflectionClass(UserController::class);\nforeach ($ref->getMethods() as $method) {\n    $attrs = $method->getAttributes(Route::class);\n    foreach ($attrs as $attr) {\n        $route = $attr->newInstance(); // Route object\n        echo \"{$route->method} {$route->path}\\n\";\n    }\n}",
    "quick_fix": "Replace @annotation docblock comments with #[Attribute] native attributes — they are parsed by PHP itself with zero reflection overhead for reading",
    "severity": "low",
    "effort": "medium",
    "created": "2026-03-15",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/attributes",
        "html_url": "https://codeclaritylab.com/glossary/attributes",
        "json_url": "https://codeclaritylab.com/glossary/attributes.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Attributes / Annotations (PHP 8.0)](https://codeclaritylab.com/glossary/attributes) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/attributes"
            }
        }
    }
}