Как получить доступ к нескольким классам через один родительский класс в PHP

Допустим, у меня есть класс, PageBuilderкоторый называется экземпляр, который я создаю, посылаю параметры и вызываю функции через мой indexфайл (который действует как фронт-контроллер). Есть три суб - классы , связанные с PageBuilderклассом: Head, Bodyи Foot, к которым обращаются , PageBuilderкоторые в основном абстрагирует их index.

Таким образом, теоретически вы можете создать экземпляр PageBuilderи иметь полный доступ к другим классам, как если бы они были частью PageBuilder.

Как я могу реализовать такой дизайн в PHP5, используя любую комбинацию классов, абстрактных классов и интерфейсов?

Я не думаю, что вышеупомянутое возможно с PHP5, не обязательно, потому что у PHP есть свои ограничения, но, возможно, потому, что я занимаюсь дизайном моего приложения неправильно.

Распространенных примеров ООП в PHP недостаточно, чтобы помочь мне понять, как структурировать более сложный дизайн.

Спасибо.

13.10.2009 04:36:57
Отредактировал теги, чтобы показать больше того, к чему вы стремитесь.
davidtbernal 13.10.2009 05:39:39
4 ОТВЕТА
РЕШЕНИЕ

Некоторые из других ответов находятся на правильном пути. Проблема, с которой вы сталкиваетесь, заключается в том, что ваш PageBuilderкласс делает слишком много. Просто название звучит неправильно для того, что вы пытаетесь с ним сделать. А PageBuilderзвучит как - то , что бы собрать кучу частей вместе в Page. Давайте назовем эти части Section. Затем, что вы хотите сделать, это использовать композицию, на что намекали несколько ответов.

Наследование часто описывается как is-aотношения, например, если ваши Sectionклассы расширяют PageBuilderкласс, тогда a Sectionявляется a PageBuilder. Что вы хотите, тем не менее, это has-aкорабль отношений, так как в вашем PageBuilderклассе есть (или много) Section(ы). Каждый раз, когда вам нужны 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(...);
    }
}

На этом этапе вы действительно изобретаете колесо, создавая дрянную систему MVC . Если это для проекта (а не для обучения), вам следует рассмотреть возможность использования одной из сред MVC для PHP. (Я рекомендую Kohana , но есть несколько вопросов относительно лучших версий PHP на Stack Overflow.) Если вы думаете об этом, MVC, вероятно, не будет для вас большим скачком.

4
23.05.2017 12:01:51
Это действительно отличная информация. Это действительно здорово, что вы можете сказать, что я думал о MVC, потому что некоторое время я пытался создать свою собственную простую инфраструктуру MVC. Я, наконец, просто сдался и начал работать над мини-структурой общего дизайна, на которой основан этот вопрос. Забавно, как все получается ... Я делаю свою собственную структуру по следующим причинам: 1) Обучение 2) Быть частью очень простого сайта, который я создаю, который не заслуживает того, чтобы я изучал большую структуру, но делая это мини рамки, я могу поцарапать мой зуд излишних. Не пытайтесь убедить меня иначе ;-).
Allen 13.10.2009 05:45:29
Просто добавить: есть ли место, где можно найти достойные учебные пособия по созданию фреймворков PHP OOP? Все очевидные, которые я нашел в Google и в книгах, были любительскими, краткими или имели какой-то серьезный недостаток в дизайне или описании. Я чувствую, что летаю вслепую! Единственные предложения, которые я когда-либо получаю, относятся к какой-то (относительно) большой платформе, такой как CakePHP, Kohana, Zend MVC и т. Д.
Allen 13.10.2009 06:07:20
Я хотел бы сделать две вещи: 1) поиграть с другими средами MVC (не обязательно только с PHP) и посмотреть, что вам нравится и не нравится в них; 2) читать книги о шаблонах проектирования в целом (объекты PHP, шаблоны и практики). это довольно хорошее \ нежное вступление, PEAA Фаулера является классическим и конкретно обсуждает MVC, Front Controller & Page Controller). Вы можете просмотреть некоторые шаблоны из PEAA онлайн по адресу: http: //☁.ws/ 넾, но в книге есть обсуждения для каждого из них, которые имеют смысл. Лично я бы оценил игру с другими фреймворками выше, чем чтение, но, возможно, вы учитесь по-другому.
davidtbernal 13.10.2009 06:26:41
Если вы собираетесь пойти по пути наполнения себя множеством PHP-фреймворков, потому что вам абсолютно необходимо изучить этот материал и создать веб-программное обеспечение, я рекомендую вам взглянуть на pradosoft.com Из множества фреймворков, с которыми я играл Кажется, один из самых инновационных.
RibaldEddie 13.10.2009 07:10:32

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
    }
}
-1
13.10.2009 05:02:36
У PHP есть интерфейсы, и вы можете реализовать их несколько. Я полагаю, что вы путаете интерфейсы и абстрактные классы и реализуете против расширения.
davidtbernal 13.10.2009 05:09:07
Я думал, что в PHP5 есть интерфейсы: php.net/manual/en/language.oop5.interfaces.php Также в приведенном выше примере, как бы я отправил много параметров функции из PageBuilder в PageSection. Например, я мог бы установить различные параметры (которые я установил бы через index.php), такие как заголовок или информация метатега?
Allen 13.10.2009 05:15:13

Из того, что я понимаю здесь, вы можете использовать составной шаблон

http://en.wikipedia.org/wiki/Composite_pattern

Ваш индекс контроллера имеет доступ только к объекту, который реализует интерфейс IPageBuilder (или похожее имя) с некоторой стандартной функцией, такой как «generatePage». Этот объект в действительности был бы своего рода контейнером, который содержит другой объект типа IPageBuilder. Эти листовые объекты могли бы создать некоторый подраздел страницы, такой как голова, тело и нога. Каждый из этих конечных объектов будет другого класса, но они будут реализовывать интерфейс IPageBuilder. Когда ваш индексный объект вызывает «generatePage», контейнер будет вызывать по порядку метод «generatePage» каждого из своих конечных объектов, который, в свою очередь, позаботится о рендеринге HTML.

Используя этот подход, если ваш класс Body становится слишком большим, вы всегда можете превратить его в контейнер, который реализует интерфейс IPageBuilder, например, запись в блоге Body может состоять из объекта Article и объекта CommentList. В этом случае объект body будет только распространять метод «generatePage» на свой дочерний объект.

Чтобы создать свой объект IPageBuilder, вы можете использовать фабричные шаблоны

http://en.wikipedia.org/wiki/Factory_method_pattern

Честно говоря, я пытался использовать такой подход в прошлом, чтобы сгенерировать свой HTML, и обнаружил, что он является излишним. Мое предложение будет вместо этого использовать шаблонизатор, как Smarty. Ваш дизайнер будет любить тебя (или ненавидеть меньше), если сделаешь это ^^.

http://www.smarty.net/

Если вы хотите знать, как использовать интерфейсы в PHP, не то чтобы это было очень сложно ...

http://ca.php.net/manual/en/language.oop5.interfaces.php

2
13.10.2009 05:14:10

Так что, если я правильно понимаю, вы хотите, чтобы Head, Body и Foot автоматически создавались как дети PageBuilder?

Есть несколько способов сделать это.

1) Создайте переменные внутри PageBuilder для хранения классов и используйте метод __call

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.

   }

}

Проблема здесь, очевидно, заключается в том, что если два класса используют один и тот же метод, то выигрывает первый. Вы могли бы, вероятно, изменить его, чтобы выбрать класс на основе имени функции довольно легко.

2) Цепь все вниз.

Abstract class Page{
}

class Head extends Page{
}

class Body extends Head{
}

class Foot extends Body{
}

class PageBuilder extends Foot{
}

В любом случае это несколько взломано, вы просто должны заставить его работать.

0
13.10.2009 05:12:26