> Le 11 juil. 2025 à 06:30, Nick <p...@nicksdot.dev> a écrit : > > Hey all, > >> On 8. Jun 2025, at 11:16, Larry Garfield <la...@garfieldtech.com> wrote: >> >> As Nick has graciously provided an implementation, we would like to open >> discussion on this very small RFC to allow `readonly` on backed properties >> even if they have a hook defined. >> >> https://wiki.php.net/rfc/readonly_hooks >> >> -- >> Larry Garfield >> la...@garfieldtech.com > > To not get this buried in individual answers to others: > > I came up with two alternative implementations which cache the computed `get` > hook value. > One leverages separate cache properties, the other writes directly to the > backing store. > > Links to the alternative branches can be found in the description of the > original PR. > https://github.com/php/php-src/pull/18757 > > I believe that these are fair solutions to address the concerns that came up > in the discussion, and I hope people will agree. > > Cheers, > Nick
Hi Nick, I think that the second alternative described as: “Cache computed get hook to it's backing store; never run the hook again” is near the most reasonable from my point of view (basing my judgment on the description, as I have not looked the actual implementation), although there are still some concerns. Advantages of that approach: 1. relatively to the first alternative solution: there is indeed no point to have a cache separate from the backing-store, as the backing-store is supposed to play that role in most cases; 2. relatively to the manual “??=” pattern, it works correctly with nullable properties. Here are my remaining concerns: A. It may be confusing to have a getter that is not always called. B. The idea of returning the value directly from the backing-store if initialised is useful also for non-readonly properties. (That can be emulated with the “??=” pattern, but only if the property is not nullable.) Both concerns may be resolved with the following amendment: * Introduce a `cached` modifier, that enables the caching semantics (i.e., not executing the getter if the backing-store is initialised). The example from the RFC would be written as: ```php readonly class LazyProduct extends Product { private DbConnection $dbApi; private string $categoryId; public Category $category { cached get => $this->dbApi->loadCategory($this->categoryId); } } ``` The `cached` modifier may be applied to any get hook, but it is mandatory if the property is readonly. (In practice, the “cached get hook” corresponds to my originally proposed “init hook”, but with the advantage of not having a separate hook.) —Claude