如何在PHP中通过一个父类访问多个类

如何在PHP中通过一个父类访问多个类,php,oop,Php,Oop,假设我有一个名为PageBuilder的类,我通过充当前端控制器的索引文件实例化它,向它发送参数并从中调用函数。PageBuilder类有三个子类:Head、Body和Foot,它们由PageBuilder访问,PageBuilder基本上将它们抽象为索引 因此,从理论上讲,您可以实例化PageBuilder并拥有对其他类的完全访问权限,就像它们是PageBuilder的一部分一样 如何使用类、抽象类和接口的任意组合在PHP5中实现这样的设计 我认为PHP5不可能实现上述功能,这不一定是因为PH

假设我有一个名为PageBuilder的类,我通过充当前端控制器的索引文件实例化它,向它发送参数并从中调用函数。PageBuilder类有三个子类:Head、Body和Foot,它们由PageBuilder访问,PageBuilder基本上将它们抽象为索引

因此,从理论上讲,您可以实例化PageBuilder并拥有对其他类的完全访问权限,就像它们是PageBuilder的一部分一样

如何使用类、抽象类和接口的任意组合在PHP5中实现这样的设计

我认为PHP5不可能实现上述功能,这不一定是因为PHP有其局限性,但可能是因为我以错误的方式设计应用程序

PHP中常见的OOP示例不足以帮助我理解如何构造更复杂的设计


谢谢。

PHP只允许您扩展一个父类,而这个父类又可以扩展另一个父类,等等。。没有接口,意味着您不能从C++中继承多个接口的函数或属性。 因此,您可能需要执行以下操作:

class PageBuilder {
    protected Head, Body, Foot;

    public function __construct($request) {
        $view = $this->getView($request);

        $this->Head = new PageSection('head.tpl');
        $this->Body = new PageSection($view);
        $this->Foot = new PageSection('foot.tpl');
    }

    private function getView($request) {
        // @todo return the template filename/path based upon the request URL
    }
}

class PageSection {
    private $template;

    public function __construct($template) {
        $this->template = $template;
    }

    public function render() {
        // @todo process and output the $this->template file
    }
}

根据我在这里的理解,你可以使用复合模式

控制器索引只能访问实现接口IPageBuilder或类似名称的对象,该对象具有一些标准函数,如generatePage。该对象实际上是某种容器,其中包含IPageBuilder类型的其他对象。这些leafs对象将能够构建页面的某些部分,如头部、身体和脚。每个叶对象都属于不同的类,但它们将实现IPageBuilder接口。当您的索引对象调用generatePage时,容器将依次调用其每个叶对象的generatePage方法,该方法将负责呈现HTML

使用这种方法,如果Body类变得太大,则始终可以将其转换为实现IPageBuilder接口的容器,例如,博客文章正文可以由一个Article对象和一个CommentList对象组成。body对象将只将generatePage方法传播到其子对象

要创建IPageBuilder对象,可以使用factory模式

老实说,我过去曾尝试过这种方法来生成我的HTML,但发现它们有点过分了。我的建议是使用模板引擎,比如Smarty。如果你这样做,你的设计师会更少地爱你或恨你

如果你想知道如何在PHP中使用接口,那不是很难


所以,如果我理解正确,您希望头部、身体和脚自动构造为PageBuilder的子项

有两种方法可以做到这一点

1在PageBuilder中创建变量以保存类,并使用_调用方法

class PageBuilder{
   private _head;
   private _body;
   private _foot;

   function __construct(){
       $this->_head = new Head();
       $this->_foot = new Foot();
       $this->_body = new Body();
   }

   function __call($name, $args){
       if(method_exists($this->_head, $name)) call_user_func_array(array($this->head, $name), $args);

       // Repeat for other classes.

   }

}
这里的问题显然是,如果两个类共享相同的方法,那么第一个出现的类将获胜。您可以很容易地修改它,根据函数名选择一个类

把所有东西都锁起来

Abstract class Page{
}

class Head extends Page{
}

class Body extends Head{
}

class Foot extends Body{
}

class PageBuilder extends Foot{
}

不管是哪种方式,它都有点被黑客攻击,你只是需要让它工作起来。

其他一些答案是正确的。你遇到的问题是你的PageBuilder类做的太多了。只是名字听起来和你想用它做的事情不符。PageBuilder听起来像是将一堆部件组装成一个页面。让我们把这些部分称为部分。然后,你要做的是使用作文,正如几个答案所暗示的那样

继承通常被描述为一种is-a关系,例如,如果节类扩展了PageBuilder类,那么节就是PageBuilder。不过,您想要的是一种has-a关系,就像在PageBuilder类中有一个或多个部分一样。任何时候,当你需要一个has-a关系时,你应该关注组合而不是继承

下面可能是您的类层次结构:

abstract class PageBuilder
{
    //@var Section
    public $header;

    //@var Section
    public $body;

    //@var Section
    public $footer;

    public function render()
    {
        echo $this->header.$this->body.$this->footer;
    }
}

class Section
{
    protected $content;
}

class LoginPage
    extends PageBuilder
{
    public function __construct()
    {
        $this->header=new Section(...);
        $this->footer=new Section(...);
        $this->body=new Section(...);
    }
}

在这一点上,你真的是在通过制造一个糟糕的系统来重新发明轮子。如果这是为了一个项目而不是为了学习,你应该考虑使用PHP的一个MVC框架。我推荐,但是有关于堆栈溢出的最佳PHP版本。如果您正在考虑这类事情,MVC对您来说可能不会是一个巨大的飞跃。

PHP有接口,您可以实现多个接口。我相信你混淆了接口和抽象类,实现和扩展。我认为PHP5确实有接口:在上面的例子中,我如何将许多函数参数从PageBuilder发送到PageSection。例如,我可以设置通过index.php设置的各种参数,例如标题或元标记信息?编辑标记以指示您获得的更多信息
在。这是非常好的信息。你可以看出我在考虑MVC,这真是太棒了,因为我已经尝试构建自己的简单MVC框架一段时间了。我终于放弃了,开始研究一个小型通用设计框架,这就是这个问题的基础。事情的发展很有趣。。。我之所以创建自己的框架,是因为以下原因:1学习2成为我正在构建的超级简单站点的一部分,这不值得我学习大框架,但通过使用这个小框架,我可以消除我的过度渴望。不要试图说服我不这样做;-。补充一句:有没有地方可以找到关于构建PHP OOP框架的不错的教程?我在谷歌和书中发现的所有明显的例子都是业余的、简短的,或者在设计或描述上有一些重大缺陷。我觉得我在瞎飞!我得到的唯一建议是指一些相对较大的框架,如CakePHP、Kohana、Zend MVC等……我会做两件事:1玩其他MVC框架,不一定只是PHP框架,看看你喜欢什么和不喜欢什么,2读关于一般PHP对象设计模式的书,Patterns&Practices是一个相当不错的介绍,Fowler的PEAA是一个经典,专门讨论了MVC、Front Controller和Page Controller。您可以通过以下网址从PEAA online浏览一些模式:http://☁.ws/넾, 但这本书对每一个问题都进行了值得讨论的讨论。我个人认为玩其他框架比阅读更重要,但也许你的学习方式有所不同。如果你想用大量的PHP框架来淹没自己,因为你绝对必须学习这些东西并制作web软件,我建议大家看看我使用过的无数框架,它似乎是最具创新性的框架之一。