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