← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Readonly Classes (PHP 8.2)

PHP PHP 8.2+ Intermediate
debt(d3/e1/b3/t5)
d3 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'default linter catches the common case' (d3), Rector and PHPStan (from detection_hints.tools) can flag classes where all properties are individually readonly and suggest the class-level readonly modifier; parse errors on PHP <8.2 are caught instantly but the missed-opportunity case needs a tool.

e1 Effort Remediation debt — work required to fix once spotted

Closest to 'one-line patch' (e1), quick_fix is literally adding the readonly keyword before class — a single-token change consolidating per-property readonly declarations.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3), applies_to scopes this to DTOs/value objects within a codebase; immutability commitment is real but contained to those classes, and consumers of value objects rarely feel the weight beyond constructing new instances instead of mutating.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap' (t5), the misconception undersells real gotchas documented in common_mistakes — static properties are not covered, clone cannot modify properties, and inheritance rules (readonly class cannot extend non-readonly and vice versa) surprise developers who assume 'all properties readonly' is the whole story.

About DEBT scoring →

Also Known As

PHP 8.2 readonly class readonly class

TL;DR

Marking an entire class readonly automatically makes all its declared properties readonly, simplifying immutable value object creation.

Explanation

PHP 8.2 extended the readonly keyword from individual properties to entire class declarations. A readonly class implicitly makes all typed, non-static properties readonly — they can only be initialised in the constructor. This is ideal for DTOs, value objects, and command/query objects. Untyped properties are not allowed in readonly classes. Cloning a readonly object with modified properties requires clone with property initialisation syntax (PHP 8.3+ adds clone with syntax). Combining with constructor property promotion gives maximally concise immutable objects.

Common Misconception

A readonly class is just a class where all properties happen to be readonly. Declaring a class readonly implicitly marks all properties readonly and prevents adding dynamic properties — it also clearly signals intent, helping static analysers enforce immutability contracts.

Why It Matters

PHP 8.2 readonly classes make all properties readonly by default — ideal for value objects and DTOs where immutability should be enforced without marking each property individually.

Common Mistakes

  • Trying to use readonly classes with properties that need to change after construction — they are for immutable objects.
  • Not knowing that readonly classes were added in PHP 8.2 — using the syntax on 8.1 causes a parse error.
  • Adding mutable static properties to readonly classes — static properties are not affected by readonly.
  • Cloning readonly class instances hoping to modify properties — clone creates an identical immutable copy.

Code Examples

✗ Vulnerable
class Point { public function __construct(
  public readonly float $x,
  public readonly float $y,
) {} }
✓ Fixed
readonly class Point { public function __construct(
  public float $x,
  public float $y,
) {} } // readonly on class covers all properties

Added 15 Mar 2026
Edited 22 Mar 2026
Views 54
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 1 ping W 1 ping T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 4 pings S 1 ping S 1 ping M 1 ping T 3 pings W 0 pings T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 1 ping W 0 pings T 0 pings F 0 pings S 2 pings S 0 pings M 1 ping T 0 pings W
No pings yet today
PetalBot 1
Scrapy 10 Amazonbot 9 Perplexity 6 Google 6 Ahrefs 4 Bing 3 ChatGPT 3 Unknown AI 2 Claude 2 PetalBot 2 Meta AI 1
crawler 41 crawler_json 7
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Low
⚡ Quick Fix
Add readonly before class to make all promoted and explicit properties readonly at once — perfect for DTOs, value objects, and query result types
📦 Applies To
PHP 8.2+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Class with all properties marked individually readonly when readonly class would cover them all; PHP 8.2+ project not using readonly classes for value objects
Auto-detectable: ✓ Yes rector phpstan
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: Medium ✓ Auto-fixable Fix: Low Context: Class


✓ schema.org compliant