代码之家  ›  专栏  ›  技术社区  ›  Alexar

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

  •  2
  • Alexar  · 技术社区  · 15 年前

    这是我的代码

    我有两种形式:

    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'
    

    这是我的表格摘要类:

    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 回复  |  直到 15 年前
        1
  •  5
  •   Nicolò Martini    15 年前

    你必须使用 反射API 访问父类的属性默认值。替换GetParentID,in Form_Abstract 有了这个,一切都很好:

    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'];
    }
    
        2
  •  3
  •   Macmade    15 年前

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

        3
  •  1
  •   Pascal MARTIN    15 年前

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

    使事情变得非常简单:当你宣布 Form_2 等级 extends Form_1 它采用了 形式2 把它们放进去 Form_1 ,覆盖已存在的内容。
    不再有“两个不同的类”:只有一个结果对象,这两者都是 形式1 形式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 .


    我想避免这种情况的解决办法是 $IID 作为 静止的 --但是请注意,它会改变代码的含义和行为方式!

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

        4
  •  0
  •   Alexar    15 年前

    我是这样做的:

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

    但是它是标准的解决方案吗 性能问题 ?