4

这是一个非常具体的问题,我在任何地方都找不到答案。这适用于许多语言,但我特别想在 PHP 中弄清楚。为此,我将使用“事件”作为我们的课程。保持简单,有两种类型:

abstract class Event{
    protected $cost;
    protected $startTime;

    public function __construct(){
        foreach($eventData as $key => $val){
            if(property_exists($this, $key)){
                $this->$key = $val;
            }
        }
    }
}

class Party extends Event{
    private $hasPointyHats;

    public function __construct($eventData){
        parent::__construct($eventData);
        $this->hasPointyHats = $eventData->hasPointyHats;
    }
}

Class Event 有 2 个道具:cost 和 startTime。当它被构造时,它应该被传递一个包含事件所有参数的关联数组,它会自动将属性设置为传递的数组值。

Class Party 通过确定该事件是否将具有那些令人敬畏的尖尖派对帽子来扩展 Event(如果没有,我不会去)。

和不。不,它没有。因为当你传递这个对象时:

//Some result set...
$mysqli_result = $result->fetch_assoc();

其中有 cost、startTime 和 hasPointyHats 值(可能更多!),您会收到以下小错误:

Fatal error: Cannot access private property Party::$hasPointyHats in C:\somePath\Event.php on line 35

我明白为什么。因为在“Event”中,$this 指的是“party”对象,但它是私有的。我不想覆盖超级构造函数中对象中的每个属性,只是那些属于超类(抽象类事件)本身的属性。有没有办法针对 Event 类的特定属性而不是子类的特定属性?这样,无论我用什么对象扩展它,我最终都不会因为传递的对象有一些冲突的属性而意外地在子类上设置属性?

我认为这是一些简单的事情,比如 super->property 或其他什么,但我仍然需要能够使用 property_exists 。

提前感谢您的帮助。

4

2 回答 2

2

您可以仅使用类名而不是对象来使用 property_exists。像这样:

abstract class Event{
protected $cost;
protected $startTime;

public function __construct($eventData){
    foreach($eventData as $key => $val){
        if(property_exists(__CLASS__, $key)){
            $this->$key = $val;
        }
    }
}
}
于 2013-06-20T05:52:29.543 回答
1

property_exists()在文档中特别指出,从 PHP 5.3 开始,它检查是否存在独立于可访问性的属性,这解释了您所看到的行为。

get_object_vars()另一方面,获取范围内已定义属性的列表,因此应该更好地满足您的目的。

尝试这样的事情:

public function __construct() {
    $props = get_object_vars($this);
    foreach ($eventData as $key => $val) {
        if (array_key_exists($key, $props)) {
            $this->$key = $val;
        }
    }
}

这并没有专门检查它是否是父类的属性,只是它可以从父类访问。

如果您真的想仅限于父类,get_class_vars()可能会更好:

public function __construct() {
    $props = get_class_vars(__CLASS__);
    foreach ($eventData as $key => $val) {
        if (array_key_exists($key, $props)) {
            $this->$key = $val;
        }
    }
}
于 2013-06-20T05:47:31.213 回答