Amit Merchant

Amit Merchant

A blog on PHP, JavaScript, and more

Readonly classes in PHP 8.2

April 29, 2022 ·

When readonly properties were introduced in PHP 8.1, it has provided a legitimate way of making class properties truly “readonly”.

Readonly properties

Before that, developers used to replicate this behavior by making the intended property private so that it kind of becomes “readonly”. Here’s an example.

class Book 
{
    private $author;    

    public function __construct(
        string $author
    ) {
        $this->author = $author;
    }
}

$book = new Book('Ruskin Bond');

$book->author = 'J. K. Rowling';
// Uncaught Error: Cannot access private property Book::$author

This approach of making properties readonly is kind of “hacky” and the biggest issue with making the property private is, if you want to access it outside of the class, you must define a getter method (getAuthor in this case) for the same like so.

class Book 
{
    private $author;    

    public function __construct(
        string $author
    ) {
        $this->author = $author;
    }

    public function getAuthor(): string 
    {
        return $this->author;
    }
}

$book = new Book('Ruskin Bond');

$book->getAuthor();
// Ruskin Bond

So, to make things less boilerplate-y, full-fledged readonly properties were introduced in PHP 8.1. So, the previous example can easily be written using readonly properties like so.

class Book 
{
    public readonly string $author; 

    public function __construct(
        string $author
    ) {
        $this->author = $author;
    }
}

$book = new Book('Ruskin Bond');

// Below will work fine
echo $book->author; // string(6) "Ruskin Bond"

$book->author = 'J. K. Rowling';
// Error: Cannot modify readonly property Book::$author

As you can tell, using readonly with a public property makes it possible to access the property outside of the class. So, no need to use getter methods anymore!

Now, to take readonly properties to the next level, we may get the readonly classes in PHP 8.2! Thanks to this RFC.

Readonly classes [RFC]

Readonly classes are just regular classes prepended by the readonly modifier.

You can call readonly classes as an extension to the readonly properties where once you make a class as readonly, it will implicitly mark all instance properties of a class as readonly.

So, if we want to make our previous example to be rewritten using readonly classes, here’s what it would look like.

readonly class Book 
{
    public function __construct(
        public string $author,
        public string $title,
    ) {}
}

$book = new Book('Ruskin Bond', 'Maharani');

$book->author = 'J. K. Rowling';
// Error: Cannot modify readonly property Book::$author

As you can tell, by making the class readonly, all the underlying class properties become readonly as well.

So, as you might have already guessed, this can be used in scenarios where you intend to make all the class properties readonly. So, you don’t have to make each class property readonly explicitly. Hence, there will be less boilerplate.

On top of this, making a class readonly will also prevent the creation of dynamic properties on the class instance (which is also going to be deprecated in PHP 8.2).

Untyped and static properties are restricted

As for restrictions, like readonly properties, it’s not possible to use untyped and static properties with readonly classes.

readonly class Book 
{
    public $author;
}

// Fatal error: Readonly property Book::$author must have type

And similarly for static properties…

readonly class Book 
{
    public static string $title;
}

// Fatal error: Readonly class Book cannot declare static properties

Only readonly class can inherit other readonly class

As for inheritance, only a readonly class can inherit other readonly classes.

readonly class Book {}

readonly class Magazine extends Book {}

Doing vice-versa would result in a fatal error.

readonly class Book {}

class Magazine extends Book {}

// Fatal error: Non-readonly class Magazine cannot 
// extend readonly class Book
class Book {}

readonly class Magazine extends Book {}

// Fatal error: Readonly class Magazine cannot 
// extend non-readonly class Book

In closing

Update: The RFC for readonly classes has now been accepted!

If implemented in PHP 8.2 (which seems like it would certainly be if we look at the number of votes in its favor on the RFC), readonly classes will be a nice addition to the already useful readonly properties.

Otherwise, if you would like to read more about this feature, you can refer to this RFC!

Learn the fundamentals of PHP 8 (includes 8.1 and 8.2), the latest version of PHP, and how to use it today with my new book PHP 8 in a Nutshell. It's a no-fluff and easy-to-read guide to the latest features and nitty-gritty details of PHP 8. So, if you're looking for a quick and easy way to PHP 8, this is the book for you.

👋 Hi there! I'm Amit. I write articles about all things web development. If you like what I write and want me to continue doing the same, I would like you buy me some coffees. I'd highly appreciate that. Cheers!

Comments?