简体   繁体   English

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

[英]PHP and Classes: access to parent's public property within the parent class

here is what my code looks like 这是我的代码的样子

i have two forms: 我有两种形式:

class Form_1 extends Form_Abstract {

    public $iId = 1;

}
class Form_2 extends Form_1 {

    public $iId = 2;

}

i expect the code behave like this: 我希望代码的行为如下:

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

here is my Form_Abstract class: 这是我的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;
    }
}

but it throws a Fatal Error: 但它会引发致命错误:

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

please help me with the method getParentId() 请帮我解决方法getParentId()

PS: i know the reason of what happens, i am seeking for the solution. PS:我知道发生了什么的原因,我正在寻求解决方案。

You have to use Reflection Api to access the parent class' property default value. 您必须使用Reflection Api来访问父类的属性默认值。 Substitute getParentId, in Form_Abstract , with this, and all works fine: Form_Abstract替换getParentId,并且一切正常:

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

    return $def_props['iId'];
}

Clearly you cannot call getParentId() in the root class, so it's better to check if a parent class exists. 显然,您无法在根类中调用getParentId(),因此最好检查父类是否存在。

UDATE: UDATE:

You can do the same with classes/objects functions: 您可以对类/对象函数执行相同的操作:

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

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

I don't think it is even possible to access the "parent"'s version of $iId : you don't actually re-define it in the child class : you only chance the value that was defined in the parent's class. 我认为甚至不可能访问$iId的“父”版本:你实际上并没有在子类中重新定义它:你只有机会在父类中定义的值。

To makes things very simple : when you declare the Form_2 class that extends Form_1 , it takes all the properties and methods of Form_2 , and put them in Form_1 , overriding what was already existing there. 为了使事情变得非常简单:当你声明Form_2该类extends Form_1 ,它需要所有的属性和方法Form_2 ,并把它们放在Form_1 ,覆盖了已经存在那里。
There is no longer "two distinct classes" : there is only one resulting object, that's both Form_1 and Form_2 at the same time. 不再有“两个不同的类”:只有一个结果对象,同时是Form_1Form_2


And here's an example that kind of -- I hope -- will help understand what I mean : 这里有一个例子 - 我希望 - 有助于理解我的意思:

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();


Using this portion of code, the call to $form2->methodInParent() will get you : 使用这部分代码,调用$form2->methodInParent()将获得:

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

ie even if calling/executing a method that's defined in the parent's class, the $iId property is still the value defined in the child class : there is one, and only one, version of that property ! 即使调用/执行在父类中定义的方法, $iId属性仍然是子类中定义的值:该属性只有一个版本!


And the call to $form2->tryingToGetParentProperty() will get you : 调用$form2->tryingToGetParentProperty()会得到你:

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

As there is no static property called $iId in Form_1 . 由于没有static称为财产$iIdForm_1


I suppose a solution to avoid that situation would be to declare $iId as static -- but note that it would change the meaning of your code, and the way it behaves ! 我想避免这种情况的解决方案是将$iId声明为static - 但请注意它会改变代码的含义及其行为方式!

ie the static variable will be shared accross all instances of the class -- which is probably not what you want ^^ static变量将在所有类的实例中共享 - 这可能不是你想要的^^

i made it work by this: 我这样做了:

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

BUT is it a standard solution, does it have any performance issue ? 但它是标准解决方案,它有任何性能问题吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM