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 $key\n";
        return array_key_exists($key,$data) ? $data[$key] : null;
    }

    public function __set($key,$value) {
        echo "set $key = $value\n";
        $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

所以这里是我的问题:

Is there a magic method or an SPL interface to implement property_exist with magically added properties ?

我不相信有办法使用魔术方法改变property_exists()的功能;这是PHPlist of available magic methods.但是,您应该可以使用任何您喜欢的逻辑来更改isset().
class test {

    private $data = array();

    public function __get($key) {
        echo "get $key\n";
        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).不如优雅,但有点好哦.

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...