PHP - Readonly Properties in PHP

 

Readonly properties are a feature introduced in PHP 8.1 that allow developers to declare class properties that can be assigned a value only once and cannot be modified afterward. This feature helps enforce immutability in objects, making code more predictable and reducing unintended side effects.


Concept of Readonly Properties

A readonly property can be initialized either at the time of declaration or within the class constructor. Once a value is assigned, it cannot be changed, unset, or reassigned anywhere else in the program.

This is particularly useful in scenarios where an object is meant to represent fixed data, such as configuration values, data transfer objects, or value objects.


Syntax and Basic Example

To declare a readonly property, the readonly keyword is used before the property declaration.

class User {
    public readonly string $name;

    public function __construct(string $name) {
        $this->name = $name;
    }
}

$user = new User("Teena");
echo $user->name; // Output: Teena

$user->name = "Rao"; // Error: Cannot modify readonly property

In this example, the property $name can only be assigned once inside the constructor. Any attempt to modify it later will result in a fatal error.


Key Characteristics

Single Assignment Rule

A readonly property can only be assigned once. This assignment must occur within the class scope, typically in the constructor.

No Modification Allowed

After initialization, the value cannot be changed, even from within the same class.

No Unsetting

Readonly properties cannot be unset using the unset() function.

Typed Properties Requirement

Readonly properties must have a declared type. PHP does not allow untyped readonly properties.


Initialization Rules

Readonly properties can be initialized in the following ways:

  1. Directly during declaration:

public readonly int $id = 10;
  1. Inside the constructor:

public function __construct(int $id) {
    $this->id = $id;
}
  1. Inside other class methods (only once and within class scope):

public function setId(int $id) {
    $this->id = $id; // Allowed only if not previously assigned
}

Use Cases

Immutable Data Objects

Readonly properties are ideal for creating immutable objects where values should not change after initialization.

Data Transfer Objects (DTOs)

When passing structured data between layers, readonly ensures that the data remains consistent.

Configuration Objects

Settings that should not be altered during runtime can be safely stored using readonly properties.


Comparison with Regular Properties

Feature Regular Property Readonly Property
Can be modified Yes No
Requires type No Yes
Supports immutability No Yes
Can be unset Yes No

Limitations

Readonly properties only enforce immutability at the property level, not for the entire object. If a readonly property holds an object or array, the contents of that object or array can still be modified.

Example:

class Test {
    public readonly array $data;

    public function __construct() {
        $this->data = [1, 2, 3];
    }
}

$obj = new Test();
$obj->data[0] = 10; // Allowed (modifying array content)

Here, the reference to the array cannot change, but the internal values of the array can still be modified.


Readonly Classes (Extension Concept)

PHP 8.2 introduced readonly classes, where all properties are implicitly readonly. This further simplifies immutable design.

readonly class Product {
    public string $name;
    public float $price;

    public function __construct(string $name, float $price) {
        $this->name = $name;
        $this->price = $price;
    }
}

Benefits

Readonly properties improve code reliability by preventing accidental data changes. They also make debugging easier because the state of an object remains consistent throughout its lifecycle. Additionally, they encourage better design practices such as immutability and cleaner architecture.


Conclusion

Readonly properties in PHP provide a structured way to enforce immutability at the property level. By allowing assignment only once, they help developers build safer and more predictable applications. This feature is especially valuable in modern PHP development where data integrity and maintainability are critical.