这是一个非常具体的问题,我无法在任何地方找到答案。 这适用于许多语言,但我特别想在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。
提前感谢您的帮助。
答案 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;
}
}
}