With PHP 8.1, a powerful new feature was introduced to the object-oriented programming (OOP) paradigm: readonly properties. This addition allows developers to define properties that can only be assigned once and are immutable after initialization. By enabling greater control over data integrity, readonly properties help you write more predictable, secure, and bug-free code.

In this article, we'll dive into what readonly properties are, how they work, and how they can be utilized effectively in modern PHP applications. We'll also cover practical examples and use cases with the latest PHP syntax.

What Are Readonly Properties?

A readonly property is a property in a PHP class that can only be assigned once, usually during object construction. Once assigned, the value of this property cannot be modified. This means that the property is essentially immutable after being set.

In a nutshell, readonly properties enforce immutability for class attributes, which helps ensure that objects maintain a consistent state throughout their lifecycle.

Key Features of Readonly Properties:

  • A readonly property can be initialized only once, either at declaration or within the constructor.
  • After it has been initialized, any attempts to modify it will result in a runtime error.
  • Readonly properties can only be declared with non-static properties.
  • They promote safer code and better data encapsulation, especially in object models with constant values or data that shouldn’t change after initialization.

Defining Readonly Properties in PHP

Let's look at the syntax to define a readonly property in a class. Here's how you can declare a readonly property in PHP 8.1+

<?php

class User {

    public readonly string $username;

    public readonly int $id;

    public function __construct(string $username, int $id) {
        $this->username = $username;
        $this->id = $id;
    }
}

$user = new User('john_doe', 101);

echo $user->username;  // Outputs: john_doe
echo $user->id;        // Outputs: 101

// Attempting to modify a readonly property will cause an error
// $user->username = 'jane_doe';  // Error: Cannot modify readonly property User::$username

 

Breaking Down the Syntax:

  • public readonly string $username;: This is how you declare a readonly property. You use the readonly keyword, followed by the visibility modifier (public, protected, or private), the data type, and the property name.

  • Inside the constructor, we can assign values to the readonly properties. Once set, these values cannot be changed during the object’s lifecycle.

  • If you try to reassign a value to a readonly property, a runtime error will occur: Error: Cannot modify readonly property.

Benefits of Readonly Properties

Readonly properties introduce several advantages to PHP developers:

  • Immutable Data Structures: Readonly properties enforce immutability, ensuring that critical data within an object remains unchanged after initialization. This is particularly useful for objects that represent fixed data such as configuration settings, user identities, or constant values.

  • Improved Data Integrity: By preventing unintended changes to object properties, readonly properties reduce bugs caused by accidental or malicious property modifications.

  • Cleaner, Simpler Code: Instead of manually managing property immutability through getter-only methods, readonly properties simplify the process by allowing you to declare immutability directly in the class definition.

  • Performance Boosts: Immutable objects are easier to optimize and manage in memory because the state doesn't change. In certain cases, this can lead to performance improvements.

Readonly Properties with Default Values

You can also assign a default value to a readonly property directly at the time of declaration:

<?php

class Config {
    public readonly string $databaseHost = 'localhost';
    public readonly int $port = 3306;
}

$config = new Config();

echo $config->databaseHost;  // Outputs: localhost
echo $config->port;          // Outputs: 3306

// $config->databaseHost = '127.0.0.1';  // Error: Cannot modify readonly property Config::$databaseHost

In this case, the readonly properties are set with default values and can't be changed after the object is instantiated.

 

Readonly Properties with Private Access

Readonly properties can also be declared with private or protected visibility, which limits access and assignment even further.

<?php

class Order {
    private readonly string $orderId;
    private readonly float $totalAmount;

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

    public function getOrderId(): string {
        return $this->orderId;
    }

    public function getTotalAmount(): float {
        return $this->totalAmount;
    }
}

$order = new Order('ORD123', 99.99);

echo $order->getOrderId();      // Outputs: ORD123
echo $order->getTotalAmount();  // Outputs: 99.99

// The following will throw errors because $orderId and $totalAmount are private readonly properties:
// $order->orderId = 'ORD124';  // Error
// $order->totalAmount = 199.99;  // Error

In this example:

  • The readonly properties orderId and totalAmount are private, making them accessible only within the class.
  • Public getter methods getOrderId() and getTotalAmount() allow safe access to these properties, but they remain immutable.

 

Use Cases for Readonly Properties

Readonly properties are especially useful in the following scenarios:

Value Objects

In Domain-Driven Design (DDD), Value Objects are immutable objects that represent a value without an identity. For example, a Currency class that encapsulates a currency’s value and code should not allow changes after its creation.

<?php

class Currency {
    public readonly string $code;
    public readonly float $value;

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

$currency = new Currency('USD', 100.50);

echo $currency->code;  // Outputs: USD
echo $currency->value; // Outputs: 100.5

// $currency->code = 'EUR';  // Error: Cannot modify readonly property Currency::$code

 

Immutable Configuration Classes

When dealing with configurations that shouldn't be modified during runtime, readonly properties help lock down values.

<?php

class AppConfig {
    public readonly string $appName;
    public readonly bool $debugMode;

    public function __construct(string $appName, bool $debugMode) {
        $this->appName = $appName;
        $this->debugMode = $debugMode;
    }
}

$config = new AppConfig('MyApp', true);

 

Ensuring Data Integrity

Readonly properties are an excellent tool for ensuring data integrity, especially when dealing with sensitive information, like user IDs or API keys, that should not change after initialization.

<?php

class ApiClient {
    public readonly string $apiKey;

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

    public function getApiKey(): string {
        return $this->apiKey;
    }
}

$client = new ApiClient('abc123xyz');
echo $client->getApiKey();  // Outputs: abc123xyz

// $client->apiKey = 'newKey';  // Error: Cannot modify readonly property ApiClient::$apiKey

 

Readonly Properties and Inheritance

Readonly properties behave consistently with PHP's inheritance model. If you inherit a class with readonly properties, you can use them just like any other property, but the readonly restriction still applies.

<?php

class ParentClass {
    protected readonly string $parentProp;

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

class ChildClass extends ParentClass {
    public readonly string $childProp;

    public function __construct(string $parentProp, string $childProp) {
        parent::__construct($parentProp);
        $this->childProp = $childProp;
    }
}

$child = new ChildClass('Parent Value', 'Child Value');
echo $child->parentProp;  // Outputs: Parent Value
echo $child->childProp;   // Outputs: Child Value

 

Conclusion

Readonly properties in PHP 8.1+ bring a much-needed enhancement to object-oriented programming by allowing for immutability in class properties. This feature simplifies the enforcement of data integrity and helps prevent unintended modifications to key values in your objects. By using readonly properties, you can write cleaner, safer, and more predictable code, especially in applications that rely on immutable data or fixed configurations.

To get the most out of this feature, remember to leverage readonly properties in situations where data should not change after initialization, such as in value objects, configuration classes, and when ensuring the security of sensitive data.

Readonly properties are another step toward making PHP a more robust and reliable language for modern application development.

Category : #php

Tags : #php

0 Shares
pic

👋 Hi, Introducing Zuno PHP Framework. Zuno Framework is a lightweight PHP framework designed to be simple, fast, and easy to use. It emphasizes minimalism and speed, which makes it ideal for developers who want to create web applications without the overhead that typically comes with more feature-rich frameworks.

Related content