PHP Readonly Properties?

But private properties exposed only using __get() aren't visible to functions that enumerate an object's members - json_encode() for example.

I regularly pass PHP objects to Javascript using json_encode() as it seems to be a good way to pass complex structures with lots of data populated from a database. I have to use public properties in these objects so that this data is populated through to the Javascript that uses it, but this means that those properties have to be public (and therefore run the risk that another programmer not on the same wavelength (or probably myself after a bad night) might modify them directly). If I make them private and use __get() and __set(), then json_encode() doesn't see them.

Wouldn't it be nice to have a "readonly" accessibility keyword?


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