PHP 8 interview question · Most asked

Explain readonly properties (8.1) and readonly classes (8.2).

Summary

A readonly property can be initialized once, from inside the declaring class scope, and never modified afterwards. A readonly class makes every declared property readonly.

Longer Answer

Readonly properties must be typed. They are initialized once (usually in the constructor) and any further write throws an Error. Note that readonly is shallow: if the property holds an object, that object's internal state can still change.

PHP 8.2 added readonly class, which marks all properties readonly and forbids dynamic properties. To produce a modified copy you write "withers" that construct a new instance. PHP 8.3 allowed re-initializing readonly properties during __clone(), which makes withers using clone possible.

Code Example

<?php
final readonly class Email
{
    public function __construct(public string $value)
    {
        if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
            throw new InvalidArgumentException("Invalid email: $value");
        }
    }

    public function withValue(string $value): static
    {
        return new static($value);
    }
}

$email = new Email('[email protected]');
// $email->value = 'x'; // Error: Cannot modify readonly property

Key Points

  • Must be typed, initialized once from class scope
  • Writes after init throw Error
  • Readonly is shallow for objects
  • readonly class (8.2) applies to all properties
  • 8.3 allows reinitialization inside __clone()

Explanation

Common mistakes

  • Assuming readonly makes nested objects immutable
  • Giving a readonly property a default value (not allowed)

Follow-up questions

  • How would you implement with methods on a readonly class before 8.3?

More most-asked PHP 8 questions

← All PHP 8 questions