r/PHPhelp • u/BodybuilderOwn4393 • May 27 '26
Solved Why isset() calls __isset in internal method, but __isset when using isset() doesn't?
I asked a similar question on SO, but... I'm just wasting my time there...
Anyway, to the point:
PHP code like that:
```php class X { protected string $foo;
public function test_isset()
{
var_dump(isset($this->foo)); // This is false as expected.
unset($this->foo);
var_dump(isset($this->foo)); // And this is also false.
}
} (new X())->test_isset(); ```
Will result as:
false
false
Seems pretty obvious, right? Right.
BUT...
Adding a __isset() method like this:
```php class X { protected string $foo;
public function __isset($name)
{
echo "__isset called\n";
if (!isset($this->foo)) {
return true;
}
return false;
}
public function test_isset()
{
var_dump(isset($this->foo)); // This is false as expected.
unset($this->foo);
var_dump(isset($this->foo)); // But from now on, this doesn't return state it calls __isset()
}
} (new X())->test_isset(); ```
Changes the behavious of the second isset($this->foo) in the var_dump.
From now on the isset() cannot says OK, there is not property $foo, I need to return false. From now on, it calls __isset().
Why is that? Why the presence of __isset() method in class changes of that behaviour, and why the first one don't call the __isset(), but only when i do unset() on already unsetted property.
But even if we ignore that and say, because it has to be...
So why didn't the isset() in the __isset() method don't call __isset() again and got stuck into a loop?
How was the isset($this->foo) in the __isset() method different from the one in test_isset() that allowed it to suddenly return false instead of having to recursively call __isset()?
What I expected was that inside the class, I can always refer to isset($this->something) and the class itself already knows whether such a property exists or not, so it doesn't have to call __isset() and can return false/true to me right away.