Readonly Properties and Classes

A readonly property can be written to only once, and only from within the scope of the class that declares it — typically inside the constructor. Any later write, from anywhere, throws an \Error. A readonly property must be typed, and cannot have a default value.

<?php
class User {
  public readonly string $name;

  public function __construct(string $name) {
    $this->name = $name; // the one and only allowed write
  }
}

$user = new User('Ann');
echo $user->name, "\n";

try {
  $user->name = 'Bob'; // second write attempt
} catch (\Error $e) {
  echo $e->getMessage(), "\n";
}
?>

Ann Cannot modify readonly property User::$name
Since PHP 8.2, an entire class can be declared readonly. Every property it declares then becomes readonly automatically — there is no need to repeat the readonly keyword on each one — and every property must be typed.

<?php
readonly class Point {
  public function __construct(
    public float $x, // automatically readonly, no keyword needed
    public float $y
  ) {
  }
}

$p = new Point(1.0, 2.0);
echo "{$p->x}, {$p->y}\n";

try {
  $p->x = 5.0;
} catch (\Error $e) {
  echo $e->getMessage(), "\n";
}
?>

1, 2 Cannot modify readonly property Point::$x
Cloning an object normally copies its readonly properties as-is. Since PHP 8.3, though, a readonly property may be reassigned from inside __clone() — letting a clone get its own independent copy of an object-valued property, instead of sharing the original.

<?php
class Post {
  public function __construct(
    public readonly DateTime $createdAt
  ) {
  }

  public function __clone(): void {
    $this->createdAt = clone $this->createdAt; // allowed only since PHP 8.3
  }
}

$p1 = new Post(new DateTime('2024-01-01'));
$p2 = clone $p1;
$p2->createdAt->modify('+1 day');

echo $p1->createdAt->format('Y-m-d'), "\n";
echo $p2->createdAt->format('Y-m-d'), "\n";
var_dump($p1->createdAt === $p2->createdAt);
?>

2024-01-01 2024-01-02 bool(false)
An anonymous class can be readonly too (see Anonymous Classes), and readonly properties are frequently combined with constructor property promotion.