DEV Community

Cover image for Final and Readonly Classes in PHP
Erland Muchasaj
Erland Muchasaj

Posted on

Final and Readonly Classes in PHP

final classes

In the past, when you didn't want other classes to extend a certain class, you could mark it as final.

Consider the code below :



<?php

namespace App\Utils;

class ParentClass
{
    public function __construct(protected string $name) {
    }
}



Enter fullscreen mode Exit fullscreen mode


<?php

namespace App\Utils;

class ChildClass extends ParentClass
{

}



Enter fullscreen mode Exit fullscreen mode

So we have a ParentClass and a ChildClass that extends the parent.

we could use the ChildClass as following:



<?php

use App\Utils\ChildClass;

$obj = new ChildClass('Antonio');

var_dump($obj);



Enter fullscreen mode Exit fullscreen mode

And this would output ChildClass public properties and also inherited properties from ParentClass as follows:

result of Dump and Die

Now if we do not want our class to be extended we just put the word final at the beginning of the class as follows:



<?php

namespace App\Utils;

final class ParentClass
{
    public function __construct(
        protected string $name,
    ) {
    }
}



Enter fullscreen mode Exit fullscreen mode

and calling the $obj = new ChildClass('Antonio'); again would result in: Class App\Utils\ChildClass cannot extend final class App\Utils\ParentClass.

So the definition of final in php is:

The final keyword is used to prevent a class from being inherited and to prevent inherited method from being overridden.

  1. So if we declare class method as a final then that method cannot be override by the child class.
  2. Same as method if we declare class as a final then that class cannot be extended any more.

readonly class

readonly classes are added on PHP 8.2.

finaland readonlyare two completely different concepts in PHP and have different implications when applied to a class.

As we saw earlier, making a class final means that it cannot be extended.



final class ParentClass{}

// Fatal error: Class ChildClass cannot extend final class ParentClass
class ChildClass extends ParentClass{}


Enter fullscreen mode Exit fullscreen mode

In the other hand, making a class readonly means several things:

  1. All instance properties of a class are implicitly marked as readonly, and cannot be reassigned.
  2. Creation of dynamic properties is not allowed.
  3. Only a readonly class can extend another readonly class.
  4. readonly properties can be overridden

For example:



// PHP 8.2+
readonly class ParentClass
{
    public function __construct(
        public string $name
    ) {}
}

$obj = new ParentClass('Antonio');
echo 'Hello, My name is ' . $obj ->name; // "Hello, My name is Antonio"


Enter fullscreen mode Exit fullscreen mode

If you try to re-assign a value to any object property after instantiation, it would throw the following error:



// PHP 8.2+
// Fatal error: Uncaught Error: Cannot modify readonly property ParentClass::$name
$obj ->name = 'Ndershkuesi';


Enter fullscreen mode Exit fullscreen mode

This happens because all properties are implicitly readonly when you mark the class as readonly.

NOTE: readonly property cannot have default value.

final and readonly

You can also mark a class as both readonly and final as well, this means:

  1. All class properties are implicitly readonly.
  2. The class cannot be extended.

Example:



// PHP 8.2+
final readonly class ParentClass {
    public function __construct(
        public string $name
    ) {}
}


Enter fullscreen mode Exit fullscreen mode

Usage:



$obj = new ParentClass('Antonio');
echo 'My name is ' . $obj->name; // "My name is Antonio"


Enter fullscreen mode Exit fullscreen mode

And if you try to assign a value to any object property or if you try to extend the class then it would throw an error as follows:



// PHP 8.2+

// Fatal error: Uncaught Error: Cannot modify readonly property ParentClass::$name
$obj->name = 'Ndershkuesi';

// Fatal error: Class ChildClass cannot extend final class Shape
readonly class ChildClass extends ParentClass {}


Enter fullscreen mode Exit fullscreen mode

Was it helpful?

Let me know in the comment section below if you ever use this package in any of your projects.

Don’t forget to like and comment.

Follow me for more web development tips, new packages and more.

Thanks for reading.

Top comments (1)

Collapse
 
htdung83 profile image
Tommy Hoang

Thanks for you effort. You still have a case that a readonly class extends readonly ParentClass. How are the constructors?

readonly class ParentClass {
    public function __construct(public string $name) {}
}

readonly class ChildClass {
    public function __construct(public string $id, public string $name) {
        _// fatal here: Cannot modify readonly property ParentClass::$name_
        parent::__construct($name);
    }
}
Enter fullscreen mode Exit fullscreen mode