PHP和类:访问父类中父项的公共属性

时间:2010-03-13 17:06:44

标签: php class object parent

这是我的代码看起来像

我有两种形式:

class Form_1 extends Form_Abstract {

    public $iId = 1;

}
class Form_2 extends Form_1 {

    public $iId = 2;

}

我希望代码的行为如下:

$oForm = new Form_2;
echo $oForm->getId(); // it returns '2'
echo $oForm->getParentId(); // i expect it returns '1'

这是我的Form_Abstract类:

class Form_Abstract {

    public $iId = 0;

    public function getId() {
        return $this->iId;
    }

/**
this method will be called from a child instance
*/
    public function getParentId() {
        return parent::$iId;
    }
}

但它会引发致命错误:

Fatal error: Cannot access parent:: when current class scope has no parent

请帮助我使用方法getParentId()

PS:我知道发生了什么的原因,我正在寻求解决方案。

4 个答案:

答案 0 :(得分:5)

您必须使用 Reflection Api 来访问父类的属性默认值。用Form_Abstract代替getParentId,并且一切正常:

public function getParentId() {
    $refclass = new ReflectionClass($this);
    $refparent = $refclass->getParentClass();
    $def_props = $refparent->getDefaultProperties();

    return $def_props['iId'];
}

显然你不能在根类中调用getParentId(),所以最好检查父类是否存在。

<强> UDATE:

您可以对类/对象函数执行相同的操作:

public function getParentId() {
    $def_values = get_class_vars(get_parent_class($this));
    return $def_values['iId'];
}

答案 1 :(得分:3)

错误是因为您正在调用没有父级的类的父级(它不扩展现有的类)。

答案 2 :(得分:1)

我认为甚至不可能访问“父”版本的$iId:你实际上并没有在子类中重新定义它:你只有机会定义的值在父母的课堂上。

使事情变得非常简单:当您声明Form_2extends Form_1时,它会采用Form_2的所有属性和方法,并将它们放在Form_1中,压倒那里已经存在的东西。
不再有“两个不同的类”:只有一个结果对象,同时是Form_1Form_2


这里有一个例子 - 我希望 - 有助于理解我的意思:

class Form_Abstract {}
class Form_1 extends Form_Abstract {
    public $iId = 1;
    public function methodInParent() {
        var_dump($this);
    }
}
class Form_2 extends Form_1 {
    public $iId = 2;
    public function tryingToGetParentProperty() {
        var_dump(parent::$iId); 
    }
}

$form2 = new Form_2();
$form2->methodInParent();
$form2->tryingToGetParentProperty();


使用这部分代码,对$form2->methodInParent()的调用将为您提供:

object(Form_2)#1 (1) {
  ["iId"]=>
  int(2)
}

即。即使调用/执行在父类中定义的方法,$iId属性仍然是子类中定义的值:该属性只有一个版本!


拨打$form2->tryingToGetParentProperty()的电话会告诉您:

Fatal error: Access to undeclared static property: Form_1::$iId

由于static中没有名为$iId的{​​{1}}属性。


我想避免这种情况的解决方案是将Form_1声明为$iId - 但请注意它会改变代码的含义及其行为方式!

即。 static变量将在所有类的实例中共享 - 这可能不是你想要的^^

答案 3 :(得分:0)

我这样做了:

public function getParentId() {
    $sClass = get_parent_class($this);
    $tmp = new $sClass;
    return $tmp->iId;
}

但它是标准解决方案,是否有任何性能问题