Property Hooks (PHP 8.4)
debt(d5/e3/b3/t5)
Closest to 'specialist tool catches it' (d5). The detection_hints list only PHPStan as a tool, with automated flagged as 'no'. Misuse — such as putting complex logic in hooks or incorrectly accessing the backing store — won't be caught by a compiler or default linter; PHPStan with custom rules or careful review is needed. This is solidly a specialist-tool catch.
Closest to 'simple parameterised fix' (e3). The quick_fix describes replacing simple getter/setter pairs with property hooks or extracting complex logic back to methods. This is a localised refactor within one class or component — not a one-line swap but not cross-cutting either. Slightly above e1 because it may touch multiple properties/methods within a class.
Closest to 'localised tax' (b3). Property hooks apply broadly (web, cli, queue-worker contexts) but misuse is contained to individual classes. Overloading hooks with complex logic creates a maintainability tax within those classes, but the rest of the codebase is largely unaffected. The scope is per-class rather than architectural.
Closest to 'notable trap' (t5). The misconception is well-documented: developers assume hooks replace all getter/setter methods, when they're only appropriate for simple validation/transformation. The common mistakes also highlight the non-obvious behaviour of backing store access ($this->property in a backed hook) and virtual property limitations. This is a documented gotcha most developers encounter when adopting the feature.
TL;DR
Explanation
public string $name { get { return $this->name; } set { $this->name = trim($value); } }. Hooks: get (called on read), set (called on write, receives $value). Virtual properties (no backing storage): public string $fullName { get => $this->first . ' ' . $this->last; }. Rules: properties with get hook are implicitly readonly from outside. set hook receives $value. Backed vs virtual: backed properties store a value, virtual derive from others. Abstract property hooks in abstract classes. Interaction with readonly: readonly properties can only have get hooks. Interface property hooks define contracts.
Common Misconception
Why It Matters
Common Mistakes
- Using hooks for complex logic — keep hooks simple, use methods for complex transforms.
- Accessing $this->property in a backed hook without understanding the backing store.
- Not knowing virtual properties (get only, no backing) can't be set directly.
Code Examples
class User {
private string $name;
public function getName(): string { return $this->name; }
public function setName(string $name): void {
$this->name = trim($name);
}
}
// PHP 8.4:
class User {
public string $name {
set => trim($value);
}
// Virtual property (no backing storage):
public string $initials {
get {
return implode('', array_map(
fn($word) => $word[0],
explode(' ', $this->name)
));
}
}
}