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.

Reply via email to