final
and readonly
are two completely different concepts in PHP and have different implications when applied to a class
.
Making a class final
means that it cannot be extended/subclassed:
final class Shape {}
// Fatal error: Class Triangle cannot extend final class Shape
class Triangle extends Shape {}
In contrast, making a class readonly
means that:
- All instance properties of a class are implicitly marked as
readonly
, and cannot be reassigned; - Creation of dynamic properties is not allowed (even with the
#[AllowDynamicProperties]
attribute); - Only a
readonly
class can extend anotherreadonly
class; readonly
properties can be overridden.
For example:
// PHP 8.2+ readonly class Shape { public function __construct( public string $name, public int $sides, ) {} } $shape = new Shape('triangle', 3); echo $shape->name . ' has ' . $shape->sides . ' sides'; // "triangle has 3 sides"
If you try to 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 Shape::$name
$shape->name = 'circle';
This happens because all properties are implicitly readonly
when you mark the class as readonly
.
You can, of course, mark as a class as both, final
and readonly
at the same time.
This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.