Re: Allow hooks in `readonly` promoted properties
| From: | Marc Bennewitz | Date: | Wed, 04 Jun 2025 13:04:08 +0000 |
| Subject: | Re: Allow hooks in `readonly` promoted properties | ||
| References: | 1 2 3 4 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-127579@lists.php.net to get a copy of this message | ||
Hi Larry,
On 03.06.25 19:03, Larry Garfield wrote:
Attachment: [application/pgp-keys] OpenPGP public key OpenPGP_0x3936ABF753BC88CE.asc
Attachment: [application/pgp-signature] OpenPGP digital signature OpenPGP_signature.asc
On Mon, Jun 2, 2025, at 11:34 PM, Nick wrote:I recently run into this limitation as well and I was under the impression, that a get property hook allows for replacing getter methods which isn't fully the case as seen here.I would like to add, personally, I don’t believe the above is dumb:It's about expectation setting. If you see a property markedclass Dumb { public readonly int $value { get => $this->value * random_int(1, 100); } }I think it is a legitimate use-case. Why wouldn’t areadonlyproperty allow us to format, cast or however mutate a “only once written value” on consumption? It will not change the underlying value. If it makes things easier for us, allow it. It’s not like this is some hidden implicit behaviour. We consciously must add the extra code, hence expect the output to be changed accordingly.readonly, it's reasonable to expect this to be true: $foo->bar == $foo->bar; For a traditional field (pre-hooks), this would be trivially true. With hooks, it may or may not be. Saying "well, that assumption doesn't hold anymore, deal" is certainly an option, but it's not an option we wanted to pursue as part of the larger RFC. But that is certainly a direction we could take.
I wanted to create an abstract class with a specific property defined to be readonly as it's supposed to be used as value object. Than in the implementation I wont to lazy load one of the expensive property values to. This RFC would resolve that limitation for me :+1 but I still don't get the logic behind it. Especially why the following is allowed from the RFC: readonlyclass LazyProduct{So, I would love to see this RFC to be implemented. Maybe you want to move it to discussion? Then my separate thread here would be obsolete.I believe at the moment that RFC text is all there is. :-) I don't know that it's worth opening a discussion without at least a mostly-done implementation. Also, Ilija is rather busy on other tasks at the moment, as am I. (Unless someone else wants to jump in to implement it, which would be fine.)
public Category$category {
get =>$this->category ??= $this->dbApi->loadCategory($this->categoryId);
}
}
but this isn't:
readonlyclass Random{
public int$value {
get => random_int(PHP_INT_MIN, PHP_INT_MAX);
}
}
While considering someone re-writes the above Random class just to make it work with a backed property:
readonlyclass Random{
public int$value {
get => ($this->value ?? 1) * random_int(PHP_INT_MIN, PHP_INT_MAX);
}
}
From the RFC text I would expect this to be allowed but it doesn't help anyone. Your described expectation isn't true anymore, the class author has more work and now it stores a needless value in memory.
Additionally, your expectation isn't true anyway as you noted in your RFC:
On the other hand, there is no shortage of dumb things that people can do with PHP already. The exact same silliness could be implemented using |__get|, for instance. ...
--Larry GarfieldThanks, Marc
Attachment: [application/pgp-keys] OpenPGP public key OpenPGP_0x3936ABF753BC88CE.asc
Attachment: [application/pgp-signature] OpenPGP digital signature OpenPGP_signature.asc