You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何添加__isset()魔术方法后,仅第二次调用isset()时才触发它?

PHP中__isset()魔术方法触发时机解析

场景1:未定义__isset()魔术方法的情况

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

该结果符合逻辑:$foo属性未被赋值,第一次isset()返回false;unset()后属性不存在,第二次isset()也返回false。

场景2:新增__isset()魔术方法的情况

与场景1一致,但新增__isset()魔术方法,调用时输出提示信息:

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()?

核心原因在于PHP对isset()调用的处理逻辑:

  1. 第一次调用:类内部定义了protected $foo属性,当前对象实例中该属性是存在的,只是未被赋值(值为null)。此时PHP会直接检查属性的存在性和值状态,因为属性存在且有权限访问,所以直接返回isset(null)的结果false,不会触发__isset()魔术方法。
  2. 第二次调用:执行unset($this->foo)后,该属性被从当前对象实例的属性集合中彻底移除。此时PHP检查$this->foo时,发现实例中已不存在该属性,于是触发__isset()魔术方法来处理这个属性检查请求,所以会输出__isset提示,之后方法内部返回isset($this->foo)的结果false。

内容的提问来源于stack exchange,提问作者LordF

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.02 06:12:27