DEV Community

Neloy Ahmed
Neloy Ahmed

Posted on

The story of readonly classes and properties in php

PHP 8.2 introduced the new feature of readonly classes. Before learning about readonly classes let's have a flashback and discuss readonly properties so that we can grasp the idea properly.

Readonly properties:

PHP 8.1 introduced the feature of readonly property. The concept of readonly property in PHP is as simple as when a class property is declared using the readonly modifier you will not be able to modify the property after initialization.

<?php

class User 
{
   public readonly string $name;

   public function __construct(string $name) {
       // Legal initialization.
       $this->name = $name;
   }
}

$john = new User("John");
// Legal read.
var_dump($john->name); // string(4) "John"

// Illegal reassignment. It does not matter that the assigned value is the same.
$john->name = "John";
// Error: Cannot modify readonly property User::$name
?>
Enter fullscreen mode Exit fullscreen mode

There are some important notes to remember about readonly properties in PHP.

  • You can only apply readonly modifier on typed properties . A readonly property without type constraints can be created using the Mixed type.

  • You can not assign readonly modifier on static properties.

class User 
{
 static readonly string $name;
// Fatal error: Static property User::$name cannot be readonly
}

Enter fullscreen mode Exit fullscreen mode
  • You can initialize the readonly property once, and only from the scope where it has been declared. Any other assignment or modification of the property will result in an Error exception.
<?php
class User 
{
  public readonly string $name;
}

$john = new User;
// Illegal initialization outside of private scope.
$john->name = "John";
// Error: Cannot initialize readonly property User::$name from global scope
?>
Enter fullscreen mode Exit fullscreen mode
  • You can not assign default value on readonly properties, because a readonly property with a default value is essentially the same as a constant, and thus not particularly useful.
<?php

class User {
    // Fatal error: Readonly property User::$age cannot have default value
    public readonly int $age = 22;
}
?>
Enter fullscreen mode Exit fullscreen mode
  • You can not unset() readonly properties once they are initialized. However, it is possible to unset a readonly property prior to initialization, from the scope where the property has been declared.

  • Not only plain assignments, any type of modification of readonly property will also result in an Error exception:

<?php

class User {
  public function __construct(
  public readonly int $age = 22,
  public readonly array $ary = [],
  ) {}
}

$john = new User;

// Cannot modify readonly property User::$age
$john->age += 1;

// Cannot modify readonly property User::$age
$john->age++;

// Cannot modify readonly property User::$age
++$john->age;

// Cannot modify readonly property User::$ary
$john->ary[] = 1;

// Cannot modify readonly property User::$ary
$john->ary[0][] = 1;

// Cannot modify readonly property User::$age
$ref =& $john->age;

// Cannot modify readonly property User::$age
$john->age =& $ref;

// Cannot acquire reference to readonly property User::$age
foreach ($john as &$prop);
?>
Enter fullscreen mode Exit fullscreen mode
  • However, objects (or resources) stored in readonly properties may still be modified internally:
<?php

class User {
  public function __construct(public readonly object $userProfile) {}
}

$john = new User(new stdClass);

// Legal interior mutation.
$john->userProfile->gender = "Male";

// Illegal reassignment.
$john->userProfile = new stdClass;

?>
Enter fullscreen mode Exit fullscreen mode

Readonly classes:

Now as we got the concept of readonly property it will be very easier for us to understand readonly classes in PHP.

If we define a class as readonly all the declared property of that class will automatically become readonly property.

readonly class User
{
    public string $name;
    public string $gender;
}
Enter fullscreen mode Exit fullscreen mode

So, User::$name and User::$gender are now readonly properties. To achieve this previously in PHP 8.1 we had to do something like:

class User
{
    public readonly string $name;
    public readonly string $gender;
}
Enter fullscreen mode Exit fullscreen mode

From this observation, we can say that readonly classes are syntactic sugar that will make all the declared properties of that class readonly properties.

So, we have to remember that, all those important notes that we described about readonly properties are still applicable here. Such as:

  1. A readonly class can not contain untyped or static properties.
  2. A readonly class's property cannot have a default value. etc.
  3. Another important note to remember about readonly classes is that A readonly class can only be extended if, the child class is also a readonly class.

That's all for today, thank you for reading.

Find me on LinkedIn
Find me on Twitter

Top comments (0)