Agent Skills: Modern PHP Language (8.1 → 8.5)

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.

UncategorizedID: fusengine/agents/php-language-modern

Install this agent skill to your local

pnpm dlx add-skill https://github.com/Fusengine/claude-plugins/tree/HEAD/plugins/php-expert/skills/php-language-modern

Skill Files

Browse the full folder contents for php-language-modern.

Download Skill

Loading file tree…

plugins/php-expert/skills/php-language-modern/SKILL.md

Skill Metadata

Name
php-language-modern
Description
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.
<objective> Covers 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].

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. </objective>

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:

  1. fuse-ai-pilot:explore-codebase - Detect the project's minimum PHP version (composer.json require.php, CI matrix)
  2. fuse-ai-pilot:research-expert - Verify a feature's version + syntax on php.net before using it
  3. 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

  1. 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.
  2. 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.
  3. Prefer enums over class constants for closed value sets — they carry type safety and methods.
  4. Prefer readonly + property hooks over hand-written getters/setters — less boilerplate, enforced immutability.
  5. 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