Documentation Index
Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
Use this file to discover all available pages before exploring further.
A readonly property in PHP is a class property that can be initialized exactly once. After initialization, its value becomes immutable for the lifecycle of the object, and any subsequent attempt to modify or unset it will result in a fatal Error.
Syntax and Initialization
The readonly modifier is applied to a property declaration. It can be used alongside visibility modifiers (public, protected, private).
class Configuration {
public readonly string $environment;
public function __construct(string $environment) {
// First initialization is legal
$this->environment = $environment;
}
}
It is frequently combined with constructor property promotion for brevity:
class Configuration {
public function __construct(
public readonly string $environment
) {}
}
Strict Technical Constraints
1. Explicit Typing Requirement
A readonly property must have an explicit type declaration. Untyped properties cannot be marked readonly. If any type is acceptable, the mixed type must be explicitly declared.
class InvalidExample {
public readonly $untyped; // Fatal error: Readonly property must have type
}
2. Scope of Initialization
A readonly property can only be initialized from within the scope of the class where it is declared. It cannot be initialized from outside the class, even if the property is public.
class State {
public readonly string $status;
}
$state = new State();
// Error: Cannot initialize readonly property State::$status from global scope
$state->status = 'active';
3. Static Modifier Prohibition
Readonly properties cannot be declared as static. The readonly modifier is strictly tied to instance properties. Attempting to combine them results in a fatal error.
class InvalidStatic {
public static readonly int $value; // Fatal error: Cannot use the static modifier on a readonly property
}
4. No Default Values
Readonly properties cannot specify a default value in their declaration. A default value constitutes an initialization, which would permanently lock the property to that value for all instances.
class InvalidDefault {
public readonly int $status = 1; // Fatal error: Readonly property cannot have default value
}
5. Unsetting is Prohibited
Once initialized, a readonly property cannot be destroyed using unset().
unset($config->environment); // Error: Cannot unset readonly property
6. Pass-by-Reference Restriction
Readonly properties cannot be passed by reference to functions or methods, as this would create a vector for bypassing the immutability constraint.
array_pop($this->readonlyArrayProperty); // Error: Cannot pass readonly property by reference
Shallow Immutability
The readonly modifier enforces a strict binding between the property and its assigned value. However, if the assigned value is an object, the internal state of that referenced object remains mutable. The readonly constraint prevents assigning a new object to the property, but does not make the referenced object itself immutable.
class Container {
public function __construct(
public readonly stdClass $data
) {}
}
$container = new Container(new stdClass());
$container->data->key = 'value'; // Legal: Mutating the referenced object's internal state
$container->data = new stdClass(); // Error: Cannot reassign the readonly property itself
Readonly Classes (PHP 8.2+)
The readonly modifier can be applied to the class declaration itself. This implicitly marks every declared property within the class as readonly and prevents the creation of dynamic properties.
readonly class User {
public string $username; // Implicitly readonly
public int $id; // Implicitly readonly
}
Reinitialization during Cloning (PHP 8.3+)
As of PHP 8.3, readonly properties can be reinitialized exclusively within the __clone() magic method. This allows for deep cloning of objects containing readonly properties.
class Document {
public function __construct(
public readonly DateTime $createdAt
) {}
public function __clone() {
// Legal in PHP 8.3+: Reinitializing during clone
$this->createdAt = clone $this->createdAt;
}
}
Master PHP with Deep Grasping Methodology!Learn More