__get访问器上的PHP empty()

lee*_*ers 26 php oop

使用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));

?>
Run Code Online (Sandbox Code Playgroud)

该功能的输出如下.比较empty()第一个和第二个结果集上的检查结果:

设置#1,意外结果:

string(19) "Accessing directly:"
string(9) "my string"
int(23)
bool(true)
bool(true)
Run Code Online (Sandbox Code Playgroud)

期望Set#1返回与Set#2相同:

string(36) "Accessing after variable assignment:"
string(9) "my string"
int(23)
bool(false)
bool(false)
Run Code Online (Sandbox Code Playgroud)

这真是令人费解和不直观.对象属性输出非空字符串,但empty()将它们视为空字符串.这里发生了什么?

Ala*_*orm 34

基于对empty手册页和注释(对于isset和/或双下划线的Ctrl-F)的阅读,看起来这是已知的行为,如果你想要你的__set__get方法并且empty在一起玩得很好,那么就有一个隐含的假设你也实现了一个__isset魔术方法.

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

  • 根据手册,使用任一功能时都应调用<a rel="nofollow noreferrer" href="http://us2.php.net/__isset"> __isset </a>.我所读到的含义是,当没有__isset函数时,没有用于调用isset或使用魔术方法清空的定义行为. (2认同)