PHP自动生成子类从父类

3

我不知道这是否可能,所以我会尽力解释清楚。

我希望有一个父类,可以轻松地通过“插件”子类进行扩展,而这些子类可能存在,也可能不存在。

class Foo {
__construct(){
   $this->foo = "this is foo";
}
}

class Bar extends Foo {
   function construct(){
    parent :: __construct;
  }
   $this->foo = "foo is now bar";
}

但我不希望每次需要它时都要使用$bar = new Bar来初始化类Bar,因为从类Foo中我不知道可用的子类是什么。理想情况下,我希望每当调用新Foo时子类自动初始化。这是否可能...有没有更好的方法可以使用子类来修改父类的每个实例中的变量?我正在WordPress中工作,所以我认为我可以给类Foo一个动作钩子,任何子类都可以钩入,但我想知道是否有一种自然的PHP方法来实现这一点。

说实话,我不确定你在问什么。你不想初始化“Bar”,但你希望“Foo”初始化所有扩展它的子类?你想在这里实现什么?我的印象是你只想让子类扩展一个基类,并操纵基类的值,使得从基类构造函数运行的代码继承自子类的值。虽然这不完全是你描述的方式,但这就是你想要的吗? - Rhys
是的,我希望Foo初始化任何扩展它的子类。我自由地承认我可能做错了,但在其最基本的形式中,我需要能够在任何时候从Foo类外部操纵Foo。实际上,我正在尝试进行扩展(尝试扩展别人的WordPress插件类),所以我正在努力弄清楚是否有一种方法来实现它。 - helgatheviking
好的,我明白了。所以,有一堆对Foo的调用正在进行中(可能由您或其他已经存在的代码调用),而您基本上希望运行自己的Foo实现,例如扩展FooBar类?您可以自由编辑 Foo本身吗? - Rhys
是的,对于第一部分我可以翻译。不,我不能自由地编辑Foo本身,但如果我能提出一个建议,使得Foo更容易扩展给我和其他人使用,那么它可能会被实现,只要它不影响当前的Foo实现。 - helgatheviking
除非您制作一个保存这些类名称的列表,否则没有“自然”的方法告诉父类它有X个子类需要初始化。这也不是继承的工作方式。您不会告诉父类创建子类,而是告诉子类它从父类借用。遗憾的是,您尝试使用的方法并不能使您的应用程序模块化,您正在按照错误的方式进行。 - N.B.
2个回答

2

根据您提供的信息,如果您确实不能以任何方式编辑Foo的实现,则您几乎没有希望。

继承对您无效,因为这需要将Bar作为实例化类,而不是Foo。当其他代码将创建类型为Foo的新对象时,您无法用Bar静默地夺取Foo的功能。

考虑到您提到它与WordPress相关,您可以始终要求插件开发人员在其init过程中添加钩子,以允许您扩展功能。这基本上是WordPress通过允许第三方代码来扩展其代码的方式。


明白了。我还在努力理解面向对象编程,所以不确定是否有我不知道的东西。你认为如果原始插件添加一个钩子并传递由父类创建的对象,我就能够从自己的文件中修改对象? - helgatheviking
好的,他们可能不想让你玩弄整个对象。通常你只能对一组数据进行“最后控制”操作。例如,他们将运行其对数组执行操作的setAttributes方法,然后在您注册的钩子上运行do_action,以便您可以在最终处理之前添加/更改属性。值得注意的是,这并不是真正的面向对象编程实践-原生WordPress并不太关心面向对象编程。 - Rhys

0

你可以像Zend这样的框架一样做到这一点。

将所有子类放在文件夹中,比如插件文件夹,并将文件名与类名相同。例如,将class Bar {}放在插件文件夹中的Bar.php文件中。

在Bar.php中进行操作。

class Bar extends Foo {
   function construct(){
    parent :: __construct;
  }
   $this->foo = "foo is now bar";
}

而类Foo将会是

class Foo {
__construct(){

foreach (glob("plugins/*.php") as $filename) // will get all .php files within plugin directory
  {
    include $filename;
    $temp = explode('/',$filename);
    $class_name = str_replace('.php',$temp[count($temp)-1]); // get the class name 
    $this->$class_name = new $class_name;   // initiating all plugins
  }


}
}

$foo = new Foo();
echo $foo->bar->foo;  //foo is now bar

希望能有所帮助,敬礼


这非常聪明。谢谢,我肯定从中学到了一些东西,但由于我是试图构建附加组件/插件的人,所以这可能对我要求父类作者有点过分了。 - helgatheviking

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接