Its focus is language features that LLMs frequently get wrong or write in a pre-8.0 style — most notably using docblock annotations (@Route, @ORM\Column) instead of native #[Attribute] syntax, which is the #1 mistake this skill exists to prevent.
Do NOT use this skill for coding style, PSR compliance, or autoloading — that is php-standards. Do NOT use it for Laravel-specific syntax conventions — that lives in the Laravel plugin.
Modern PHP Language (8.1 → 8.5)
Agent Workflow (MANDATORY)
Before writing PHP, spawn 3 agents in parallel, one Agent call each with a name:
- fuse-ai-pilot:explore-codebase - Detect the project's minimum PHP version (
composer.json require.php, CI matrix)
- fuse-ai-pilot:research-expert - Verify a feature's version + syntax on php.net before using it
- mcp__context7__query-docs - Cross-check idiomatic usage
After writing, run fuse-ai-pilot:sniper for validation.
Overview
| Feature |
Since |
Use it for |
| Enums (backed + methods/interfaces) |
8.1 |
Closed sets of values with behavior |
First-class callable syntax f(...) |
8.1 |
Passing callables without strings |
| readonly properties / classes |
8.1 / 8.2 |
Immutable value objects / DTOs |
#[\Override] |
8.3 |
Fail-fast on broken inheritance |
Property hooks get/set |
8.4 |
Computed/validated properties, no getter/setter boilerplate |
Asymmetric visibility public private(set) |
8.4 (static: 8.5) |
Public read, restricted write |
Lazy objects newLazyGhost() |
8.4 |
Deferred initialization in DI containers |
Pipe operator |> |
8.5 |
Left-to-right data transformation chains |
clone() function + $withProperties |
8.5 |
Immutable "with" updates, incl. readonly |
#[\NoDiscard] |
8.5 |
Enforce return-value consumption |
Critical Rules
- Attributes, never docblock annotations - Native
#[Attribute] replaces @annotation docblocks for routing, ORM, DI, validation. This is the #1 LLM mistake — see attributes-over-docblocks.md.
- Check the target PHP version first - Never emit 8.5 syntax on an 8.1 project. Read
composer.json require.php before choosing a feature.
- Prefer enums over class constants for closed value sets — they carry type safety and methods.
- Prefer
readonly + property hooks over hand-written getters/setters — less boilerplate, enforced immutability.
declare(strict_types=1); at the top of every file.
Architecture
src/
├── Enum/
│ └── Status.php # backed enum + interface + methods
├── ValueObject/
│ └── Money.php # readonly class, clone() with $withProperties
└── Model/
└── User.php # property hooks, asymmetric visibility
→ See modern-class.md for complete working code
Reference Guide
Concepts
| Topic |
Reference |
When to Consult |
| PHP 8.5 features |
php-85-features.md |
Pipe operator, clone(), #[\NoDiscard], static aviz |
| PHP 8.4 features |
php-84-features.md |
Property hooks, aviz, lazy objects, #[\Deprecated] |
| 8.1–8.3 baseline |
php-81-83-baseline.md |
Enums, readonly, fibers, #[\Override] |
| Attributes vs docblocks |
attributes-over-docblocks.md |
Any metadata: routing, ORM, DI, validation |
Templates
| Template |
When to Use |
| modern-class.md |
Writing a new class the modern way |
Best Practices
DO
- Read
require.php before picking a feature version
- Use enums with interfaces + methods for stateful value sets
- Use property hooks for validation/computation instead of magic
__get
- Use the pipe operator to flatten nested calls (8.5+)
DON'T
- Write
@Route/@ORM\Column docblock annotations — use attributes
- Emit 8.4/8.5 syntax without confirming the project supports it
- Hand-roll getters/setters when hooks or
readonly fit
- Guess a feature's version — verify on php.net
1---2name: php-language-modern3description: Use when writing modern non-framework PHP 8.1-8.5 — property hooks, asymmetric visibility, pipe operator, attributes, enums, readonly. Do NOT use for style (php-standards) or Laravel.4---56<objective>7Covers modern PHP language features from 8.1 through 8.5 outside any framework: backed enums with methods/interfaces, first-class callable syntax, readonly properties/classes, the #[\Override] attribute, property hooks (get/set), asymmetric visibility, lazy objects (newLazyGhost()), the pipe operator (8.5), the clone() function with $withProperties, and #[\NoDiscard].89Its focus is language features that LLMs frequently get wrong or write in a pre-8.0 style — most notably using docblock annotations (@Route, @ORM\Column) instead of native #[Attribute] syntax, which is the #1 mistake this skill exists to prevent.1011Do NOT use this skill for coding style, PSR compliance, or autoloading — that is php-standards. Do NOT use it for Laravel-specific syntax conventions — that lives in the Laravel plugin.12</objective>1314# Modern PHP Language (8.1 → 8.5)1516## Agent Workflow (MANDATORY)1718Before writing PHP, spawn 3 agents in parallel, one `Agent` call each with a `name`:19201. **fuse-ai-pilot:explore-codebase** - Detect the project's minimum PHP version (`composer.json` `require.php`, CI matrix)212. **fuse-ai-pilot:research-expert** - Verify a feature's version + syntax on php.net before using it223. **mcp__context7__query-docs** - Cross-check idiomatic usage2324After writing, run **fuse-ai-pilot:sniper** for validation.2526---2728## Overview2930| Feature | Since | Use it for |31|---------|-------|------------|32| **Enums (backed + methods/interfaces)** | 8.1 | Closed sets of values with behavior |33| **First-class callable syntax** `f(...)` | 8.1 | Passing callables without strings |34| **readonly properties / classes** | 8.1 / 8.2 | Immutable value objects / DTOs |35| **`#[\Override]`** | 8.3 | Fail-fast on broken inheritance |36| **Property hooks** `get`/`set` | 8.4 | Computed/validated properties, no getter/setter boilerplate |37| **Asymmetric visibility** `public private(set)` | 8.4 (static: 8.5) | Public read, restricted write |38| **Lazy objects** `newLazyGhost()` | 8.4 | Deferred initialization in DI containers |39| **Pipe operator** `\|>` | 8.5 | Left-to-right data transformation chains |40| **`clone()` function + `$withProperties`** | 8.5 | Immutable "with" updates, incl. readonly |41| **`#[\NoDiscard]`** | 8.5 | Enforce return-value consumption |4243---4445## Critical Rules46471. **Attributes, never docblock annotations** - Native `#[Attribute]` replaces `@annotation` docblocks for routing, ORM, DI, validation. This is the #1 LLM mistake — see [attributes-over-docblocks.md](references/attributes-over-docblocks.md).482. **Check the target PHP version first** - Never emit 8.5 syntax on an 8.1 project. Read `composer.json` `require.php` before choosing a feature.493. **Prefer enums over class constants** for closed value sets — they carry type safety and methods.504. **Prefer `readonly` + property hooks over hand-written getters/setters** — less boilerplate, enforced immutability.515. **`declare(strict_types=1);`** at the top of every file.5253---5455## Architecture5657```58src/59├── Enum/60│ └── Status.php # backed enum + interface + methods61├── ValueObject/62│ └── Money.php # readonly class, clone() with $withProperties63└── Model/64 └── User.php # property hooks, asymmetric visibility65```6667→ See [modern-class.md](references/templates/modern-class.md) for complete working code6869---7071## Reference Guide7273### Concepts7475| Topic | Reference | When to Consult |76|-------|-----------|-----------------|77| **PHP 8.5 features** | [php-85-features.md](references/php-85-features.md) | Pipe operator, `clone()`, `#[\NoDiscard]`, static aviz |78| **PHP 8.4 features** | [php-84-features.md](references/php-84-features.md) | Property hooks, aviz, lazy objects, `#[\Deprecated]` |79| **8.1–8.3 baseline** | [php-81-83-baseline.md](references/php-81-83-baseline.md) | Enums, readonly, fibers, `#[\Override]` |80| **Attributes vs docblocks** | [attributes-over-docblocks.md](references/attributes-over-docblocks.md) | Any metadata: routing, ORM, DI, validation |8182### Templates8384| Template | When to Use |85|----------|-------------|86| [modern-class.md](references/templates/modern-class.md) | Writing a new class the modern way |8788---8990## Best Practices9192### DO93- Read `require.php` before picking a feature version94- Use enums with interfaces + methods for stateful value sets95- Use property hooks for validation/computation instead of magic `__get`96- Use the pipe operator to flatten nested calls (8.5+)9798### DON'T99- Write `@Route`/`@ORM\Column` docblock annotations — use attributes100- Emit 8.4/8.5 syntax without confirming the project supports it101- Hand-roll getters/setters when hooks or `readonly` fit102- Guess a feature's version — verify on php.net