On Tue, Feb 25, 2025, at 5:31 PM, tight.fork3...@fastmail.com wrote:
> On 2/25/25 4:51 PM, Rowan Tommins [IMSoP] wrote:
>> I actually started writing an RFC to rationalise some of this behaviour
>
> I'm glad I'm not the only one who considers this an issue worth pursuing!
>
>> Here are some of the things that might happen as a result of 
>> unset($foo->bar):
>
> I don't disagree that there's a lot of weirdness. But for better or 
> worse that's where PHP is now - it's a fundamentally weird language. I 
> think it's better to be consistently weird than to be inconsistently 
> weird. It would be inconsistent to allow unsetting some types of 
> properties but not others, and which ones can and can't be unset are 
> indistinguishable to a 3rd-party consumer. That's a footgun - the fact 
> that it's caused by an evolution of weirdness is neither here nor there.
>
>> If we allow a hooked property to directly "unset" the backing value, what 
>> *exactly* will it do? 
>
> I can't comment from an implementation perspective, but as a user of 
> PHP I would expect unsetting a backed property to return the property 
> the "uninitialized" state, and subsequent access would proceed as if it 
> were the first access of the uninitialized property.
>
> Unsetting a virtual property could simply do nothing, but not result in 
> a fatal error. I don't think a warning is even necessary because no 
> action is taken.
>
>> If we add an "unset" hook, what's the default behaviour if one isn't defined?
>
> Adding an unset hook could be out of scope of this proposal, but if 
> there's sentiment that one should be added, not defining one would 
> result in the behavior described above. I certainly don't want to be 
> required to define an unset hook for every single backed property; 
> rather `unset()` should have a default behavior.
>
>> I think it's one of those features that sounds simple when you look at a 
>> single use case, but actually specify the behaviour in all cases is going to 
>> be a lot of work. 
>
> Definitely. I do think that hard things are worth pursuing in the 
> interest of consistency and functionality. But then again I'm not the 
> one implementing it!

Most of the use cases you talk about are easily emulated from within the class. 
 If you're calling unset($foo->bar) from outside of the class, I would argue 
the code is bad and needs to be rethought to begin with.

>From within the class, the RFC linked to several examples, the first few of 
>which involved caching of derived properties.

https://github.com/Crell/php-rfcs/blob/master/property-hooks/examples.md

Most notably for now:

class User
{
    private array $cache = [];

    // ...

    public string $fullName { get => $this->cache[__PROPERTY__] ??= 
$this->first . " " . $this->last; }
}

And then internal to the class, unset($this->cache['fullName']) works 
perfectly.  Problem solved.

And as noted, if you're calling unset() on a property from outside the object, 
PHP isn't the problem.  Bad code design is the problem.  Fix that instead.

--Larry Garfield

Reply via email to