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 Overflow
๐ŸŒ
PHP
php.net โ€บ manual โ€บ en โ€บ language.oop5.properties.php
PHP: Properties - Manual
Prior to PHP 8.4.0 a readonly property is implicitly private-set, and may only be written to from the same class. As of PHP 8.4.0, readonly properties are implicitly protected(set), so may be set from child classes.
๐ŸŒ
Stitcher
stitcher.io โ€บ blog โ€บ readonly-classes-in-php-82
Readonly classes in PHP 8.2 | Stitcher.io
PHP 8.2 adds a new way of declaring classes: you can make them readonly. In practice, it means that all properties of that class will be readonly.
๐ŸŒ
Stitcher
stitcher.io โ€บ blog โ€บ php-81-readonly-properties
PHP 8.1: readonly properties | Stitcher.io
Important note: PHP 8.2 adds a way of making whole classes readonly at once: readonly classes. Writing data transfer objects and value objects in PHP has become significantly easier over the years. Take for example a look at a DTO in PHP 5.6: class BlogData { /** @var string */ private $title; /** @var Status */ private $status; /** @var \DateTimeImmutable|null */ private $publishedAt; /** * @param string $title * @param Status $status * @param \DateTimeImmutable|null $publishedAt */ public function __construct( $title, $status, $publishedAt = null ) { $this->title = $title; $this->status = $s
๐ŸŒ
dailycomputerscience
dailycomputerscience.com โ€บ post โ€บ complete-guide-on-readonly-properties-in-php
Complete Guide on Readonly Properties in PHP
October 11, 2024 - The readonly properties orderId and totalAmount are private, making them accessible only within the class.
๐ŸŒ
Reddit
reddit.com โ€บ r/php โ€บ when should one use read-only properties / classes?
r/PHP on Reddit: When should one use read-only properties / classes?
July 1, 2024 -

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 :)

๐ŸŒ
PHP Tutorial
phptutorial.net โ€บ home โ€บ php oop โ€บ php readonly properties
PHP Readonly Properties
April 7, 2025 - Because of this, PHP only supports readonly on a typed property. If you attempt to use the readonly keyword with a property without a type, youโ€™ll get an error. For example: <?php class User { public readonly $username; } Code language: PHP (php)
Find elsewhere
๐ŸŒ
Stitcher
stitcher.io โ€บ blog โ€บ readonly-or-private-set
Readonly or private(set) | Stitcher.io
For the record, it's totally ok to construct an object without a value for a readonly property. PHP will only check a property's validity when reading it; that was part of the design of typed properties back in PHP 7.4:
๐ŸŒ
PHP
wiki.php.net โ€บ rfc โ€บ readonly_properties_v2
PHP: rfc:readonly_properties_v2
This RFC introduces a readonly property modifier, which prevents modification of the property after initialization. Value objects are often immutable: Properties are initialized once in the constructor, and should not be modified afterwards. PHP currently has no way to enforce this constraint.
๐ŸŒ
Medium
medium.com โ€บ @sjoerd_bol โ€บ creating-immutable-objects-in-php-a-look-at-private-constructor-and-public-readonly-166b1d9dff59
Creating Immutable Objects in PHP: A Look at Private Constructor and Public Readonly | by Shadowtje | Medium
April 2, 2023 - A class with public readonly properties can be considered immutable only if the properties themselves are truly immutable. In other words, if the values of the properties cannot be changed after they are set, then the class can be considered immutable. However, if the properties can be changed after they are set, then the class cannot be considered truly immutable. Itโ€™s important to note that in PHP, there is no native support for truly immutable objects or properties.
Top answer
1 of 1
14

readonly properties allow you to create immutable objects, or at the very least immutable properties (since 8.2 we also have readonly for classes, which allow creating immutable objects without having to apply the keyword to each of the class properties).

That way, you can be sure that a value won't be changed by accident after being initialized, throughout the object's life.

It's a very similar concept to constants (set via const or define), albeit with two important differences:

  • constants need to be defined on "compilation" time, whereas readonly properties will be set during runtime, usually during on object instantiation (so multiple instances will be able to hold different values*)
  • constants live in the global scope; and in case of class constants, their value is tied to the class and not to the instance.

You could achieve the same with a private property only accessible via a getter. E.g., in "the olden days":

class Foo {

    private DateTimeImmutable $createAt;

    public function __construct() {
        $this->createdAt = new DateTimeImmutable();
    }

    public function getCreatedAt(): DateTimeImmutable
    {
        return $this->createdAt;
    }
}

$f = new Foo();
echo $f->getCreatedAt()->format('Y-m-d H:i:s');

The only problem with this is that it requires a lot of boilerplate code.

With PHP 8.1, almost the same could be achieved by doing:

class Foo
{

    public function __construct(
        public readonly DateTimeImmutable $createdAt = new DateTimeImmutable()
    )
    { }

}

$f = new Foo();
echo $f->createdAt->format('Y-m-d H:i:s')

And since PHP 8.2 add readonly classes, it gets even better, since one can do:

readonly class Foo
{

    public function __construct(
        public string $name,
        public DateTimeImmutable $createdAt = new DateTimeImmutable()
    )
    { }

}

And now both Foo::name and Foo::createdAt are readonly, and can only be set during object instantiation.

๐ŸŒ
Lindevs
lindevs.com โ€บ readonly-properties-in-php-8-1
Readonly Properties in PHP 8.1 | Lindevs
January 26, 2023 - Let's say we have User class which has readonly property. ... <?php class User { private readonly int $id; public function setId(int $id): void { $this->id = $id; } }
๐ŸŒ
Alex Web Develop
alexwebdevelop.com โ€บ home โ€บ php readonly properties: how to use them
PHP Readonly Properties: How to Use Them - Alex Web Develop
August 6, 2023 - This is a technical limitation [โ€ฆ] In conjunction with the questionable usefulness of readonly static properties, this is not considered worthwhile at this time.โ€ ยท Similarly, I like the fact that assignment from outside of the class is not allowed (like for private properties, but reading is still allowed with public).
๐ŸŒ
LinkedIn
linkedin.com โ€บ pulse โ€บ power-php-8-public-readonly-properties-christian-vermeulen
The power of PHP 8 public readonly properties ๐Ÿ’ช
August 30, 2022 - We can now add the "readonly" keyword to make sure the property can not be changed during runtime, making the property immutable. This takes away the need to encapsulate the property in getters.
๐ŸŒ
Dogan-ucar
dogan-ucar.de โ€บ startseite โ€บ do readonly properties replace getters (in php)?
Do Readonly Properties replace Getters (in PHP)?
January 21, 2025 - Readonly Properties in PHP 8.1 ยท I am in programming since around 2006 and started coding with Borland C++ (I can hear you saying โ€œBor -whatโ€). Back that time, we created Desktop UI applications with object oriented C++ and together with the language, we learned best practices and common approaches (to object oriented programming). One major rule of thumb โ€“ among others โ€“ is: make members private and create getters and setters for each.