php empty() 在__get访问器上

2022-08-30 14:37:17

使用 PHP 5.3,我在应用于通过重载函数获取的动态对象属性时遇到了奇怪/非直观的行为。请考虑以下代码段:empty()__get()

<?php

class Test {

  protected $_data= array(
   'id'=> 23,
   'name'=> 'my string'
  );

  function __get($k) {
    return $this->_data[$k];
  }

}

$test= new Test();
var_dump("Accessing directly:");
var_dump($test->name);
var_dump($test->id);
var_dump(empty($test->name));
var_dump(empty($test->id));

var_dump("Accessing after variable assignment:");
$name= $test->name;
$id= $test->id;
var_dump($name);
var_dump($id);
var_dump(empty($name));
var_dump(empty($id));

?>

此函数的输出如下所示。比较对第一个和第二个结果集的检查结果:empty()

设置 #1,意外结果:

string(19) "Accessing directly:"
string(9) "my string"
int(23)
bool(true)
bool(true)

期望集合 #1 返回与集合 #2 相同的结果:

string(36) "Accessing after variable assignment:"
string(9) "my string"
int(23)
bool(false)
bool(false)

这真的很令人困惑和不直观。对象属性输出非空字符串,但将其视为空字符串。这是怎么回事?empty()


答案 1

根据对的手册页和注释(Ctrl-F表示设置和/或双下划线)的阅读,看起来这是已知的行为,如果您希望您的和方法一起玩得很好,那么有一个隐含的假设,即您也实现了一个神奇的方法。__set__getempty__isset

这有点不直观和令人困惑,但这往往发生在大多数元编程中,特别是在像PHP这样的系统中。


答案 2

在此示例中,empty() 调用 __isset() 重载函数,而不是 __get() 重载函数。试试这个:

class Test {

  protected $_data= array(
   'id'=> 23,
   'name'=> 'my string'
  );

  function __get($k) {
    return $this->_data[$k];
  }

  function __isset($k) {
    return isset($this->_data[$k]);
  }

}

推荐