Skip to content

PHP Tutorial Modern PHP Features

Readonly Classes

Lesson 226 of 369 2 min read By Deepak Paswan Updated Oct 5, 2026

Writing readonly on every property gets repetitive. PHP 8.2 adds a readonly class: put the keyword on the class, and every property becomes readonly.

index.php
PHP
<?php
readonly class Address
{
    public function __construct(
        public string $street,
        public string $city,
        public string $postcode,
    ) {}
}

$a = new Address("12 Park Road", "Pune", "411001");

echo $a->city . "\n";

try {
    $a->city = "Delhi";
} catch (Error $e) {
    echo $e->getMessage();
}
Output
OUTPUT
Pune
Cannot modify readonly property Address::$city

It is the same as writing public readonly on each property, with less noise.

Compare

index.php
PHP
<?php
// PHP 8.1
final class Point
{
    public function __construct(
        public readonly float $x,
        public readonly float $y,
    ) {}
}

// PHP 8.2
readonly class Point
{
    public function __construct(
        public float $x,
        public float $y,
    ) {}
}

Rules

  • All properties must be typed (a readonly property needs a type).
  • You cannot declare static properties in a readonly class.
  • You cannot add dynamic properties (creating undeclared ones fails).
  • A child class of a readonly class must also be readonly.
index.php
PHP
<?php
readonly class Temperature
{
    public function __construct(public float $celsius) {}

    public function toFahrenheit(): float
    {
        return $this->celsius * 9 / 5 + 32;
    }

    public function plus(float $degrees): static
    {
        return new static($this->celsius + $degrees);
    }
}

$t = new Temperature(20);

echo $t->toFahrenheit() . " / " . $t->plus(5)->celsius;
Output
OUTPUT
68 / 25

Good fits

  • Value objects: money, date range, coordinates, email.
  • Data transfer objects (DTOs): a bundle of values that moves between layers.
  • Configuration objects.

Not a good fit

  • A class whose state changes over time (a cart, a counter, an account).
  • Entities that are loaded and updated by an ORM that sets properties after creation.

Remember what readonly does not cover

As with readonly properties, the object inside a property can still change. See Readonly Properties.

Version

Needs PHP 8.2 or newer. On PHP 8.1, readonly class is a parse error. In that case, put readonly on each property.

info
Pairing with final
Most readonly classes are also final. A value object that cannot change and cannot be extended is simple to reason about: final readonly class Money {}.