为什么对于动态属性使用__get()的对象也必须实现__isset()?

时间:2018-04-04 18:15:06

标签: php oop

我正在研究array_column如何工作,我已经读过如果将此函数应用于属性为private / protected的对象数组,则__get__isset的实现是需要。但我不明白为什么__isset本身可以访问这些属性时使用__get

<?php

class Person{
    private $name;

    public function __construct(string $name)
    {
        $this->name = $name;
    }

    public function __get($prop)
    {
        return $this->$prop;
    }

    public function __isset($prop) : bool
    {
        return isset($this->$prop);
    }
}

$people = [
    new Person('Fred'),
    new Person('Jane'),
    new Person('John'),
];

print_r(array_column($people, 'name'));
?>

I have found this related question,但我找不到答案。

2 个答案:

答案 0 :(得分:2)

经过一番思考,我找到了令我信服的东西,即array_column函数在每个属性上应用isset函数,这需要将__isset魔法方法实现到每当在受保护/私有财产上调用isset()时要调用的类

答案 1 :(得分:0)

使用__get的对象不需要__isset

array_column函数使用__isset来检查是否应该抓取privateprotected属性。

__isset之前使用__get的目的是确保它应该获取现有属性值。

它相当于在使用之前检查数组值:

// Initialize array with not fully expected data
$myArray = getValues();
if(isset($myArray['myColumn']))
{
    echo $myArray['myColumn'];
}

在你的示例类中,php将为内部的每个Person实例做这样的事情:

if($persion->__isset('name'))
{
    return $person->__get('name');
}

注意:使用isset($this->$prop)是一个坏主意,因为它会在null值上返回false!

改为使用property_exists,即:

public function __isset($prop) : bool
{
    return property_exists($this, $prop);
}