PHP Class 在运行时动态扩展

PHP Class dynamically extending in runtime

是否可以在 PHP 中动态扩展 class 对象?最优雅的方法是什么?

进一步解释的示例代码:

class BasicClass {

    private $variable;

    public function BasicFunction() {
        // do something
        $this->variable = 10;
    }

}

class ExtendedClass extends BasicClass {

    public function ExtendedFunction() {
        // do something else with basic class variable
        return $this->variable/2;
    }

}

$A = new BasicClass();

If(condition for extension){

    // A should be of class ExtendedClass
    // and the current class variables should be kept
    // ... insert the magic code here ...
    // afterwards we would be able to use the ExtendedFunction with the original variables of the object

    $A->ExtendedFunction();

}

解决这个问题的一种方法是创建一个新的 ExtendedClass 对象并从旧对象复制所有变量。但这可以做得更优雅吗?

是的。有可能的。一种方法是使用 anonymous classes 或简单地覆盖 class 本身(在你的情况下 $A)但这意味着更多的逻辑并且它不那么干净,所以我不会'不进去。

注意:在 PHP 7.

中添加了对匿名 classes 的支持

使用上面的示例,我们可以编写以下代码(我更改了 属性 的可见性,以便能够在扩展 class 中使用它。我建议您添加a getter 而不是改变可见性)。

class BasicClass {

  public $variable;

  public function BasicFunction() {
    // do something
    $this->variable = 10;
  }

}

class ExtendedClass extends BasicClass {

  public function ExtendedFunction() {
    // do something else with basic class variable
    return $this->variable / 2;
  }

}

$A = new BasicClass();

if (TRUE) {

  // A should be of class ExtendedClass
  $A = new class extends ExtendedClass {

  };

  $A->ExtendedFunction();
}

请注意,这将覆盖 $A。您仍然会在其中拥有所有可用的方法,因为这样做不会丢失继承。


显然,无论您采用哪种方法,都不是最干净的方法。

我的回答是正确的,但如果您要编辑您的问题并提供更多详细信息,说明您希望通过这样做实际实现的目标,也许另一种方法更合适。


您也可以使用 eval 和可能的 Reflection 实现一些魔法,但它们太神奇了,我拒绝写答案,因为它助长了这种不良做法。