---
applyTo: "**/*.php"
description: Modern PHP conventions
---

# PHP 8.4

- Start files with `declare(strict_types=1);` where the project does. Follow PSR-12 / the repo's PHP-CS-Fixer or Pint config.
- Type everything: parameters, return types (including `void`, `never`), and properties. Use union and nullable types instead of docblock-only types; add generics in PHPDoc (`@return list<Order>`) for static analysis.
- Value objects and DTOs as `final readonly class` with constructor property promotion.
- Enums (backed `enum Status: string`) instead of class constants for fixed sets.
- Use `match` over `switch` for value mapping; first-class callables (`strlen(...)`) and named arguments where they help readability.
- Property hooks and asymmetric visibility (`public private(set)`) are available in 8.4; use them only if the codebase already does.
- Exceptions: throw specific exception classes; never suppress errors with `@`.
- Database access through the framework ORM or PDO prepared statements; never interpolate input into SQL.
- Escape output for the context (`htmlspecialchars` or the template engine).
- Composer: add deps with `composer require`; don't edit `composer.lock` by hand.

## Check
PHPStan/Psalm at the configured level and the test suite (PHPUnit or Pest) pass.
