> 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




Reply via email to