Hi Nicolas Thanks for your proposal. I have some unpolished thoughts.
On Fri, May 1, 2026 at 11:38 AM Nicolas Grekas <[email protected]> wrote: > > https://wiki.php.net/rfc/exists-magic-method >From what I can tell there are two primary objectives stated in the RFC: 1. Solve the "null or undefined" ambiguity problem. 2. Allow materializing properties within the "property existence check" magic method, whether that be __isset() or __exists(), and avoiding the __get() call that normally follows. As for objective 1, it seems quite odd to me that __exists() indicates "the property is declared and may or may not be null", when is then used for all the constructs that ask the distinct question "is the property defined and not null?", namely for isset(), empty() (negated) and ??. That's the question already precisely answered by __isset(). The behavior for disagreeing __isset() and __get() methods is odd, but IMO this is a clear userland bug. The other stated benefit is having the ability to check whether a property exists even if it may be null by calling __exists() directly. IMO the use-cases are narrow. For declared properties, there's a slightly unconventional solution: `array_key_exists('property', (array)$object)`. For virtual properties; fair enough. Though these could also use hooks nowadays. As for objective 2, you've mentioned this is possible to implement for __isset() but was rejected in GH-12695 due to complexity and performance concerns. IMO a new method does not address these concerns, it just moves them. If the __exists() method is intended to replace __isset() long-term, then, once all code has migrated, performance will not differ from adding the check to __isset(). [1] Similarly, complexity for implementing the __isset() and __exists() should be roughly equivalent. You solved the soundness issues mentioned in the RFC by avoiding repetition of the entire function and copying the relevant paths. I believe something similar should work for __isset(). It's also worth noting the main objection in GH-12695 was to treat it as a bug and change behavior in stable versions. To summarize, in my personal opinion it's better to go back to the original idea and add another property existence check after the __isset() call that avoids calling __get() if the property has materialized. From what I can tell, the has_property handler will also need the same adjustments. I don't think the stated benefits are enough to warrant a full migration to a new method. Ilija [1] We also concluded in the issue that performance isn't a real issue anyway. __exists() would also perform worse due to having to call __get() to verify the value is not null. This does make sure the functions are in agreement, at the cost of an unnecessary call for correct code.
