Named Arguments in Attributes
debt(d5/e1/b2/t3)
Closest to 'specialist tool catches' (d5). PHPStan (listed in detection_hints.tools) can detect misuse of attribute arguments, including type mismatches or invalid parameter names. However, the detection is not automatic by default — requires static analysis configuration. Basic syntax errors would be caught at parse time, but semantic issues like positional arg fragility require tooling.
Closest to 'one-line patch' (e1). The quick_fix states to simply use named arguments in attribute constructors — this is a single-line change per attribute usage. Converting #[Route('/path', 'GET')] to #[Route(path: '/path', methods: 'GET')] is a trivial inline modification.
Closest to 'minimal commitment' (b1), scored at b2. Named arguments in attributes are a local syntax choice affecting individual annotations. They don't create cross-cutting dependencies or architectural constraints. However, once a codebase adopts named args in attributes, there's mild consistency pressure to use them everywhere for uniformity, creating a small ongoing tax.
Closest to 'minor surprise' (t3). The misconception field indicates developers may expect special syntax for attribute named args when there is none — it's identical to regular named arguments. This is a small learning curve rather than a serious trap, as the syntax is consistent with PHP 8.0+ named arguments elsewhere. The edge case around PHP version requirements (8.0+ for named args, 8.1+ for attributes with named args) adds minor confusion.
TL;DR
Explanation
PHP attributes (#[AttributeName]) can accept constructor arguments. With named arguments (PHP 8.0+), attribute arguments can be passed by name rather than position, making complex attributes readable. This is especially useful for framework attributes with many optional parameters. Attribute classes are defined with #[Attribute] and a regular constructor. Named args in attributes follow the same rules as named args in regular function calls — you can reorder, skip optional ones, and the code is self-documenting.
Common Misconception
Why It Matters
Common Mistakes
- Using positional args in attributes with many parameters — order-sensitive and fragile.
- Forgetting attribute class must be declared with #[Attribute] and has a constructor.
- Using named args for attributes in PHP < 8.0 — named args require 8.0.
Code Examples
#[Route('/home', ['GET'], true, 'home_route')]
class HomeController {}
#[Route(
path: '/home',
methods: ['GET'],
requiresAuth: false,
name: 'home_route'
)]
class HomeController {}