> On 2 Dec 2022, at 18:31, Ilija Tovilo <tovilo.il...@gmail.com> wrote:
> 
> Hi Stephen
> 
>> So here’s my last attempt:
>> 
>> Please change this behaviour in your rfc.
>> 
>> You are explicitly making it mutually exclusive with readonly now, so that’s 
>> not a bc break - if/when it becomes compatible with readonly the authors of 
>> that rfc can either keep the limitation as it exists **for readonly 
>> properties** (I’m not an expert but I don’t believe this would be a BC break 
>> either), or decide to drop the limitation completely (deliberate BC break)
>> 
>> Keeping the limitation now on non-readonly properties makes no sense, and 
>> will be confusing to user land developers.
> 
> This behavior is already not limited to readonly, it works the same
> for normal typed properties.
> https://3v4l.org/WpBp4
> 
> The set-visibility is not relevant here: When unset has been called,
> __set will be called (and __get too). The set-visibility is only
> relevant when unset hasn't been called, as that will influence whether
> the property is written to or an error is thrown. The RFC is actually
> wrong saying this is specifically due to readonly properties. This
> behavior has been here for a while.
> 
> See the relevant commit:
> https://github.com/php/php-src/commit/f1848a4b3f807d21415c5a334b461d240b2a83af
> 
>> Assigning to an uninitialized typed property will no longer trigger
>> a call to __set(). However, calls to __set() are still triggered if
>> the property is explicitly unset().
> 
>> This gives us both the behavior people generally expect, and still
>> allows ORMs to do lazy initialization by unsetting properties.
> 
>> For PHP 8, we should fine a way to forbid unsetting of declared
>> properties entirely, and provide a different way to achieve lazy
>> initialization.
> 
> I'm not sure if anybody actually makes use of this trick. It might be
> worth removing this weird behavior by offering an alternative. In any
> case, this is out of scope for this RFC.
> 
> Regards,
> Ilija
> 
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Hi Ilija

I’m not sure if you missed my earlier emails but I’m pretty sure you’ve 
misunderstood what I’m asking about.

I’m not, and have never, asked for the behaviour of explicitly unset() 
properties to change. Not once, never, nada. I do agree that the behaviour 
weird, but its weird in a way that gives userland developers more 
power/capability, not less.


What I *am* asking for, is that when a non-readonly property is declared with 
protected or private `set` visibility, an attempt to set/write that property 
from outside the class will trigger __set(), exactly the way it does now for a 
property declared as protected or private.

If it’s not obvious the major reason for this is to allow dropping  __get 
boilerplate while maintaining the ability to have checks/custom logic on 
set/write (i.e. a poor mans property set accessor), and thus existing code that 
uses this can easily and safely upgrade to using asymmetric visibility without 
affecting the __set handler logic.


To make it crystal clear, here is an example:

```
class FooSym {
   protected string $bar;

   public function __set($name, $value) {
      if ($name === 'bar') {
         $this->bar = $value;
      }
   }

   public function __get($name) {
      if ($name === 'bar') {
         return $this->bar;
      }
   }
}

$f = new FooSym;
$f->bar = 'hello';
echo $f->bar;


class FooAsym {
   public protected(set) string $bar;

   public function __set($name, $value) {
      if ($name === 'bar') {
         $this->bar = $value;
      }
   }

}

$f = new FooAsym;
$f->bar = 'hello';
echo $f->bar;

```

The first class is a trivial example of what works right now. No use of unset() 
is required, it behaves as expected.

The proposed __set behaviour in this RFC will mean the second example **won’t 
work**, and that is both extremely unintuitive and IMO, technically unnecessary 
with regards to avoiding BC breaks.

Cheers

Stephen 





Reply via email to