Php 在不可访问对象上使用empty与_isset和_get

Php 在不可访问对象上使用empty与_isset和_get,php,getter,magic-methods,Php,Getter,Magic Methods,我希望在\uuu isset上获得相同的结果或另一次通过,但不是直接调用\uu get。还是我在这里遗漏了什么?读这里 isset()只关心存在,而不关心虚无 empty()考虑数据类型,为了考虑数据,它需要值 在第一次调用empty时,它试图“获取”meta,以便测试meta中的“notExisting”是否为空$meta只是一个没有magic方法的通用std类,因此您不会得到任何输出(它不调用magic_方法::_get,因为$meta不是magic_方法的实例) 在第二次调用empty时

我希望在
\uuu isset
上获得相同的结果或另一次通过,但不是直接调用
\uu get
。还是我在这里遗漏了什么?

读这里

  • isset()只关心存在,而不关心虚无
  • empty()考虑数据类型,为了考虑数据,它需要值

    • 在第一次调用empty时,它试图“获取”meta,以便测试meta中的“notExisting”是否为空$meta只是一个没有magic方法的通用std类,因此您不会得到任何输出(它不调用magic_方法::_get,因为$meta不是magic_方法的实例)


      在第二次调用empty时,它检查是否设置了meta,它就是这样设置的,因此isset返回true。正如claudrian所说,empty取决于值,因此它会尝试“获取”meta next,以便确定值是否为空。它不是空的,因此空返回false。如果您将第二个调用更改为empty,改为isset,它只调用返回true的isset。

      我明白了,但我觉得很奇怪:empty是否因为我请求属性而假设设置了Magic_方法中的$meta?当直接请求$meta时,它放弃了这个假设。这是出于设计,还是我的想法不正确?empty()无法知道$meta的状态…@David在第一次调用中,您没有在meta上检查empty。您正在获取meta并在
      notExisting
      上检查为空。如果您对变量调用empty,比如
      $test->foo->bar->blah
      ,您是否希望它对访问的每个属性调用empty,“foo”,“bar”和“blah”?您只需要调用一个函数,从左到右,您将从“$test”($test->foo)获取“foo”,然后从“foo”(foo->bar)获取“bar”,然后从“bar”(bar->blah)获取“blah”,最后检查“blah”是否为set/empty。$test->foo->bar->blah的返回值是传递/签入的空值。啊哈!从右到左检查?现在,这很有道理,为什么它现在跳过了这个集合。
      <?php
      
      class Magic_Methods
      {
          protected $meta;
      
          public function __construct() 
          {
              $this->meta = (object) array(
                  'test' => 1
              );
          }
      
          public function __isset($name) 
          {
              echo "pass isset {$name} \n";
      
              return isset($this->$name);
          }
      
          public function __get($name) 
          {
              echo "pass get {$name} \n";
      
              return $this->$name;
          }
      }
      
      $mm = new Magic_Methods();
      
      $meta = empty($mm->meta->notExisting);
      
      var_dump($meta);
      
      echo "||\n";
      
      $meta = empty($mm->meta);
      
      var_dump($meta);
      
      pass get meta 
      bool(true)
      ||
      pass isset meta 
      pass get meta 
      bool(false)