php – 检查属性是否存在于神奇的属性上
有很多关于这个问题的问题,特别是
this one,但这并没有帮助我.
在property_exists和isset之间有歧义,所以在提出我的问题之前,我要指出一点: property_exists property_exists检查对象是否包含属性而不查看其值,它只查看其visibility. 所以在下面的例子中: <?php class testA { private $a = null; } class testB extends testA { } $test = new testA(); echo var_dump(property_exists($test,'a')); // true // parent's private property becomes invisible for its child $test = new testB(); echo var_dump(property_exists($test,'a')); // false isset isset检查属性中是否存在值,如果值等于false,则检查是否未设置. <?php $var = null; echo var_dump(isset($var)); // false $var = ''; echo var_dump(isset($var)); // true $var = false; echo var_dump(isset($var)); // true $var = 0; echo var_dump(isset($var)); // true $var = '0'; echo var_dump(isset($var)); // true isset和property_exists在神奇添加的属性上的行为 一个属性可以存在一个空值,所以我不能使用__isset魔术方法知道一个属性是否存在.我也不能使用property_exists,因为使用魔法方法添加属性. 这是一个例子,但这只是一个例子,因为在我的应用程序中,魔术设置的属性被存储在对象外部. class test { private $data = array(); public function __get($key) { echo "get $keyn"; return array_key_exists($key,$data) ? $data[$key] : null; } public function __set($key,$value) { echo "set $key = $valuen"; $this->data[$key] = $value; } public function __isset($key) { echo sprintf("isset $key ( returns %b )",isset($this->data[$key])); return isset($this->data[$key]); } } $test = new test(); $test->x = 42; isset($test->x); // 1 $test->y = null; isset($test->y); // 0 property_exists($test,'y'); // 0 所以这里是我的问题:
我不相信有办法使用魔术方法改变property_exists()的功能;这是PHP的
list of available magic methods.但是,您应该可以使用任何您喜欢的逻辑来更改isset().
class test { private $data = array(); public function __get($key) { echo "get $keyn"; return array_key_exists($key,array_key_exists($key,$this->data)); return array_key_exists($key,$this->data); } } $test = new test(); $test->x = 42; isset($test->x); // 1 $test->y = null; isset($test->y); // 1 这通过魔术方法覆盖其功能来有效地修复了(烦人的)问题与isset和null.而不是在__isset()中使用isset(),而是使用array_key_exists(它将按预期处理null).因此__isset()在设置空值时返回预期结果. 这有一个缺点,即覆盖的功能不会产生与default isset()功能相同的结果.因此,如果此对象需要与其他(可能是stdClass)对象透明地使用,则isset()将为此类的对象中的空值返回true,对于正常对象中的空值为false. 根据您的需求,这可能是或可能不是一个可行的解决方案.如果上述问题是一个障碍,那么另一个选择可能是定义一个具有keyIsSet()属性的接口,并将该接口应用于要测试的所有对象.然后使用$obj-> keyIsSet(‘key’)而不是isset($obj-> $key).不如优雅,但有点好哦. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |