
A new keyword readonly introduced in PHP 8.1 allows to declare a property as readonly using the readonly keyword.
The Readonly class properties feature in PHP 8.1 marks a property as readonly using A new keyword “readonly“. A class property declared as readonly can be initialized once and further changes to this property is not permitted. For this reason readonly properties can be used in cases you need to prevent write access to certain properties directly.
class Post { public readonly int $sid; public function __construct(int $sid) { $this->sid = $sid; } } $post = new Post(199); echo $post->sid;
As you see we marked the property $sid as readyonly. Note that readonly properties applies only to typed properties. Any attempt to declare a non typed property as readonly will show an error like so:
public readonly $sid;
Fatal error: Readonly property Post::$sid must have type in .....
Another aspect is that we can’t set a readyonly property directly. To set a readonly property from the class itself using the constructor as in this example or from another method:
class Post { public readonly int $sid; public function setSid($sid) { $this->sid = $sid; } } $post = new Post(); $post->setSid(200);
Here in this example i added a method to set the readonly property $sid. If you attempt to initialize the the readonly propety $sid more than once it show an error:
$post = new Post(); $post->setSid(200); $post->setSid(300);
Fatal error: Uncaught Error: Cannot modify readonly property Post::$sid in ....
Also you can’t initialize a readonly property outside the scope of the class otherwise an error will be thrown:
$post = new Post(); $post->sid = 150; echo $post->sid;
Fatal error: Uncaught Error: Cannot initialize readonly property Post::$sid from global scope in ....
Here setting the property directly show error although the property marked as public.
Readonly Property and unset()
The php unset() function can not be used alongside with readonly property to unset the property:
$post = new Post(); unset($post->sid);
Fatal error: Uncaught Error: Cannot unset readonly property Post::$sid from global scope in ...
Readonly Property and promoted constructors
If you remember the promoted constructor feature in PHP 8.0 which allows property declaration and class assignment be done through the constructor itself.
Example:
class Post { public int $sid; public function __construct(int $sid) { $this->sid = $sid; } }
Which is equivalent to
class Post { public function __construct(public int $sid) {} }
Now we can use the readonly property alongside the promoted constructors like so:
class Post { public function __construct(public readonly int $sid) {} } $post = new Post(122); echo $post->sid;
Readonly Vs Const
PHP OOP already includes the const keyword which may seem to serve a similar purpose like readonly, however there are many differences between the functionalities of the two keywords:
- Class constant must have a default value
- Can’t set class constant at runtime inside the constructor or from another method in contrast to readonly property.
- Class constant allocated once per class and not per class instance.
- Class constant referenced inside the class using class name or the “self” keyword.
- Class constant referenced outside the class using class name.
class Post { public const sid=20; } echo Post::sid;
Attempting to set a class constant will raise an error:
class Post { public const sid=20; public function __construct(int $sid) { self::sid = $sid; // invalid } } // Parse error: syntax error, unexpected token "=" in ...
So a class constant supposed to have a predefined value set in the declaration step of this constant and can’t be changed afterwards.