1

是否可以在 PHP 中动态扩展类对象?这样做最优雅的方式是什么?

一些示例代码用于进一步解释:

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 的新对象并从旧对象复制所有变量。但这可以更优雅地完成吗?

4

1 回答 1

3

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

注意:在 PHP 7 中添加了对匿名类的支持。

使用上面的示例,我们可以编写以下代码(我更改了属性的可见性以便能够在扩展类中使用它。我建议您添加一个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. 您仍将拥有所有可用的方法,因为这样做不会丢失继承。


显然,无论您采取哪种方法都不是您可以做到这一点的最干净的方法。

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


您也可以使用evaland来实现一些魔法Reflection,但它们是如此神奇,我拒绝写答案,因为它促进了这种不良做法。

于 2018-02-20T11:27:11.107 回答