You can do it like this:
class Example {
private $__readOnly = 'hello world';
function __get($name) {
if($name === 'readOnly')
return $this->__readOnly;
user_error("Invalid property: " . __CLASS__ . "->$name");
}
function __set($name, $value) {
user_error("Can't set property: " . __CLASS__ . "->$name");
}
}
Only use this when you really need it - it is slower than normal property access. For PHP, it's best to adopt a policy of only using setter methods to change a property from the outside.
Answer from too much php on Stack OverflowWhen should one use read-only properties / classes?
What's the benefit of readonly properties over constants?
oop - What is the benefit of readonly in PHP 8.1? - Stack Overflow
Can we revive the readonly properties discussion?
Property accessors is a much better way to go than adding a readonly keyword. It's a shame that RFC failed. I don't know the reasons but you could try searching the mailing list to find any discussions around the time (try externals.io if they have stuff from back then).
More on reddit.comVideos
You can do it like this:
class Example {
private $__readOnly = 'hello world';
function __get($name) {
if($name === 'readOnly')
return $this->__readOnly;
user_error("Invalid property: " . __CLASS__ . "->$name");
}
function __set($name, $value) {
user_error("Can't set property: " . __CLASS__ . "->$name");
}
}
Only use this when you really need it - it is slower than normal property access. For PHP, it's best to adopt a policy of only using setter methods to change a property from the outside.
Since PHP 8.1 there are implemented native readonly properties
Documentation
You can initialize readonly property only once during the declaration of the property.
class Test {
public readonly string $prop;
public function __construct(string $prop) {
$this->prop = $prop;
}
}
--
class Test {
public function __construct(
public readonly string $prop,
) {}
}
Trying to modify the readonly propety will cause following error:
Error: Cannot modify readonly property Test::$prop
Update PHP 8.2
Since PHP 8.2 you are able to define as readonly a whole class.
readonly class Test {
public string $prop;
public function __construct(string $prop) {
$this->prop = $prop;
}
}
I discovered this feature a few weeks ago and end up using it a lot in my DTOs (most times they end up being read-only classes).
Right now, the only other use case I have for it is for class properties injected via dependency injection, which I believe should probably never be changed to anything else than what it was first instantiated as.
I'm not sure if the DI properties is a good excuse for using read-only, or if there are other use cases I might have missed, which is why I'm asking how you guys use it :)
After all, the overlap is so big that I struggle to see why they were introduced.
If you want a property to be immutable after assignment, a constant does that, too. That's also why constants being public is fine.
So, I would have found readonly more useful, if I was allowed to always re-assign them from inside the class that defined them. Then they would work like a private property that only has a getter but no setter - which I find convenient. It's the job of the class to manage its state, so I don't see why you shouldn't be allowed to re-assign them from inside when constants already exist.
Care to enlighten me?