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

发布于 2024-08-25 00:16:46 字数 854 浏览 8 评论 0原文

这是我的代码,

我有两种形式:

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

< strong>PS:我知道发生这种情况的原因,我正在寻找解决方案。

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:

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

PS: i know the reason of what happens, i am seeking for the solution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夏末的微笑 2024-09-01 00:16:46

您必须使用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'];
}

You have to use Reflection Api to access the parent class' property default value. Substitute getParentId, in Form_Abstract, with this, and all works fine:

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.

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'];
}
刘备忘录 2024-09-01 00:16:46

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

The error is because you are calling the parent of a class that does not have a parent (it does not extend an existing class).

旧时模样 2024-09-01 00:16:46

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

让事情变得非常简单:当您声明 扩展 Form_1Form_2 类时,它会获取 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< /code> 属性仍然是子类中定义的值:该属性只有一个版本!

调用 $form2->tryingToGetParentProperty() 将会得到:

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

因为 中没有名为 $iIdstatic 属性表格_1

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

static 变量将在类的所有实例中共享——这可能不是您想要的 ^^

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.

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.

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.

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 :

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

i.e. 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 !

And the call to $form2->tryingToGetParentProperty() will get you :

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

As there is no static property called $iId in Form_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 !

i.e. the static variable will be shared accross all instances of the class -- which is probably not what you want ^^

再浓的妆也掩不了殇 2024-09-01 00:16:46

我是这样工作的:

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

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

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文