为什么isset() 并不总是调用内部的 __isset() 魔术方法?

编程语言 2026-07-09

第一个场景代码:

class X
{
    protected string $foo;

    public function test_isset()
    {
        var_dump(isset($this->foo));
        unset($this->foo);
        var_dump(isset($this->foo));
    }
}
(new X())->test_isset();

结果是:

false
false

看起来挺合理的——可以。

第二个场景代码:

这与上面相同,只是在类中多了一个额外的 __isset() “魔术”方法。请注意,当它被调用时,它有一行会 echo 某事:

class X
{
    protected string $foo;

     public function __isset($name)
     {
         echo "__isset\n";
         return isset($this->foo);
     }

    public function test_isset()
    {
        var_dump(isset($this->foo)); // false
        unset($this->foo);
        var_dump(isset($this->foo)); // false
    }
}
(new X())->test_isset();

结果:

false
__isset
false

问题

为什么添加额外的内部 __isset() 函数会让它调用这个函数,而我只是在第二次使用 isset() 时才会?

解决方案

__isset() 是在对不可访问(受保护或私有)或不存在的属性调用 isset()empty() 时触发的。

当属性存在时,isset 可以直接回答这个问题。
将属性取消设置后,该属性变得不存在。用 isset 再次测试该属性时,isset 会遇到一个不存在的属性,并看到一个被重载的 __isset 方法,因此调用它。

这不会导致 __isset 调用 __isset 递归从而进入无限循环,因为:

PHP不会在同一个被重载的方法内部再次调用被重载的方法。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章