Skip to content
PHP News
Search
Declined PHP 8.6

__exists(), a magic method for distinguishing "missing" from "set to null"

Adds an opt-in __exists() magic method that says if a magic property exists, separate from whether it's null, used by isset(), empty() and ??.

Add __exists() magic method?

Primary vote · 2/3 majority

2 Yes 13 No 7 abstain 13% approval

This poll has closed.

Declined. Voting closed on June 28, 2026 with 2 in favor, 13 against and 7 abstaining. It needed a two-thirds majority.

Summary

PHP's __isset() magic method is asked to answer two questions at once: does this property exist, and is it not null? It can only return one bool, so it can't answer both. This RFC from Nicolas Grekas proposed a new magic method, __exists(), that only answers whether the property exists. It was declined.

Arrays already have both tools. isset() tells you a key is set and not null, while array_key_exists() tells you the key is there even if its value is null. Objects with magic properties have no equivalent of the second one. The RFC also points out that isset($x) ? $x : $y and $x ?? $y are supposed to behave the same, but on magic properties they don't.

How it would have worked

You'd add __exists() to a class. It has to be public, non-static and declare a bool return type:

class C {
    private array $store = ['nullProp' => null];

    public function __exists(string $n): bool {
        return array_key_exists($n, $this->store);
    }

    public function __get(string $n): mixed {
        return $this->store[$n] ?? null;
    }
}

$c = new C;
var_dump($c->__exists('nullProp')); // bool(true)
var_dump(isset($c->nullProp));      // bool(false)

When a class defines __exists(), PHP calls it instead of __isset() for isset(), empty() and ??. If it returns false, PHP stops there and never calls __get(). If it returns true, PHP fetches the value and does the usual null check. That brings isset() and ?? back into agreement.

A class could define both methods. Older PHP versions would keep using __isset(), and newer ones would use __exists(). property_exists() would not change.

What it means for existing code

Nothing would have broken. The method is opt-in, so classes without __exists() behave exactly as they do today. Method names starting with __ are already reserved for PHP, so the name was never really available to userland code. Static analyzers and IDEs would have needed to learn about the new method.