patternphplaravelTip
PHP 8.1 Readonly Properties for Immutable Value Objects
Viewed 0 times
PHP 8.1+
readonlyimmutablevalue objectDTOconstructor promotionphp 8.1php 8.2
Error Messages
Problem
PHP DTOs and value objects need to be immutable after construction but enforcing this requires manual guarding or convention-based discipline. Adding a setter breaks the contract silently.
Solution
Declare constructor properties as readonly. They can be written exactly once (during initialisation) and never mutated afterward. PHP 8.2 adds readonly classes where all properties are implicitly readonly. Use constructor promotion to declare and initialise in one expression.
Why
readonly enforces immutability at the language level with zero runtime cost. Any attempt to write to a readonly property after initialisation throws an Error. This makes DTOs, commands, and events safe to pass around without defensive cloning.
Gotchas
- readonly properties must be typed—untyped properties cannot be readonly
- readonly does not mean deep immutability—an object property that is readonly can still have its own mutable internal state
- Cloning a readonly object requires re-declaring all values in __clone(), which is verbose; PHP 8.4 adds with-expression
- readonly class (PHP 8.2) makes all declared properties readonly implicitly
Code Snippets
Readonly DTO with constructor promotion
class CreateOrderCommand
{
public function __construct(
public readonly int $userId,
public readonly string $productSku,
public readonly int $quantity,
) {}
}
$cmd = new CreateOrderCommand(userId: 1, productSku: 'ABC', quantity: 3);
$cmd->quantity = 5; // Error: Cannot modify readonly propertyRevisions (0)
No revisions yet.