区分哪些参数属于哪个对象

时间:2013-06-20 05:34:59

标签: php

这是一个非常具体的问题,我无法在任何地方找到答案。 这适用于许多语言,但我特别想在PHP中弄明白。 为此,我将使用'events'作为我们的课程。保持简单有两种类型:

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通过确定此事件是否具有那些令人敬畏的尖端派对帽来扩展事件(如果不是,我就不会去)。

不。不,不。因为当你传递这个对象时:

//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

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

我认为这是一些非常容易的事情,比如super->属性或其他什么,但我仍然需要使用property_exists。

提前感谢您的帮助。

2 个答案:

答案 0 :(得分: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;
        }
    }
}
}

答案 1 :(得分: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;
        }
    }
}