In PHP 8.1
, readonly
properties were introduced, which allow you to declare class properties that can only be set once during object initialization and cannot be modified thereafter. This feature brings more immutability to PHP classes, enhancing code reliability and readability. Here's an explanation along with examples:
Syntax:
class MyClass {
public readonly string $name;
public readonly int $age;
public function __construct(string $name, int $age) {
$this->name = $name;
$this->age = $age;
}
}
- The
readonly
keyword is used to declare properties that are immutable after initialization. - These properties must be initialized either at the point of declaration or within the constructor.
- Once initialized, their values cannot be modified throughout the object's lifetime.
Example:
class Person {
public readonly string $name;
public readonly int $age;
public function __construct(string $name, int $age) {
$this->name = $name;
$this->age = $age;
}
}
$person = new Person("Zero", 24);
echo "Name: " . $person->name . ", Age: " . $person->age . "\n";
// Trying to modify readonly properties will result in a fatal error
// $person->name = "Jane";
// $person->age = 25;
In this example, the Person
class has readonly
properties $name
and $age
. They are initialized within the constructor. Once initialized, their values cannot be changed.
If you uncomment the lines trying to modify the readonly
properties, PHP will throw a fatal error indicating that the properties are read-only and cannot be modified.
Benefits:
- Immutability: Readonly properties ensure that once set, their values remain constant throughout the object's lifetime, enhancing predictability and reducing unexpected side effects.
- Code Safety: It prevents accidental modification of properties, reducing the chances of bugs and making code more robust.
- Readability: By indicating that certain properties are readonly, it clarifies the intent of the class and its usage to other developers.
Overall, readonly properties in PHP 8.1
offer a convenient way to create more immutable and reliable classes.
More examples:
Example 1: Immutable Point Class
class Point {
public readonly float $x;
public readonly float $y;
public function __construct(float $x, float $y) {
$this->x = $x;
$this->y = $y;
}
public function __toString(): string {
return "($this->x, $this->y)";
}
}
$point = new Point(5.5, 3.2);
echo "Point coordinates: $point\n";
In this example, the Point
class represents a point in a two-dimensional space. Both $x
and $y
properties are declared as readonly
. Once initialized in the constructor, they cannot be modified. This ensures that the coordinates of a point remain immutable after creation.
Example 2: Immutable Configuration Class
class Configuration {
public readonly array $settings;
public function __construct(array $settings) {
$this->settings = $settings;
}
public function get(string $key) {
return $this->settings[$key] ?? null;
}
}
$config = new Configuration(['debug' => true, 'max_connections' => 10]);
echo "Debug mode: " . ($config->get('debug') ? 'On' : 'Off') . "\n";
Here, the Configuration
class stores an array of settings. The $settings
property is declared as readonly
to ensure that once the configuration is initialized, it cannot be altered. This helps maintain the integrity of configuration data.
Example 3: Readonly Properties in Inheritance
class ParentClass {
public readonly string $parentProperty;
public function __construct(string $parentProperty) {
$this->parentProperty = $parentProperty;
}
}
class ChildClass extends ParentClass {
public readonly string $childProperty;
public function __construct(string $parentProperty, string $childProperty) {
parent::__construct($parentProperty);
$this->childProperty = $childProperty;
}
}
$child = new ChildClass('Parent', 'Child');
echo "Parent Property: {$child->parentProperty}, Child Property: {$child->childProperty}\n";
In this example, ChildClass
extends ParentClass
, and both classes have readonly
properties. Even in inheritance, the readonly
nature of properties is maintained, ensuring that once set, properties cannot be modified.
These examples showcase how readonly
properties can be used to create immutable objects and maintain data integrity in various scenarios.