PHP MVC - один класс представления для всех контроллеров против класса представления для каждого контроллера - PullRequest
0 голосов
/ 27 мая 2019

Я создаю PHP-фреймворк, основанный на MVC, в основном для целей обучения. У меня в основном есть фреймворк, и я создаю на нем приложение и совершенствую фреймворк по мере продвижения.

Я все еще не уверен в некоторых аспектах архитектуры такого рода, и в данный момент я подвергаю сомнению мою реализацию части View.

Как я настроил мою структуру:

Это очень простая настройка, например: вы переходите на URL /post/post_id, это загрузит index.php, который будет создавать экземпляр маршрутизатора. Затем маршрутизатор проверит URL-адрес и создаст соответствующий контроллер и метод на основе URL-адреса. В этом случае это будет PostController, а метод будет методом по умолчанию, который будет использовать post_id для получения данных постов из соответствующей модели. Затем контроллер установит переменную «data», которая будет содержать данные для передачи в View, и это то, где я запутался - если он отправит свой собственный объект View (файл класса представления, выделенный для PostController), или к общепринятому классу View, который используется всеми контроллерами для загрузки html-файла?

В данный момент мой контроллер отправляет данные в класс View, эти данные включают в себя, какой файл шаблона должен быть включен / показан, и фактические данные для страницы (что мы получили от Модели через контроллер).

У меня такой вопрос:

Если в системе этого типа есть один объект View, который отображает все представления (html-файлы) в зависимости от того, какие данные передаются в метод "render", или каждый контроллер, отправляющий данные в View, имеет свой собственный Посмотреть объект / класс?

Это означает, должен ли PostController отправлять запрос в класс общего вида, тот же, который используется всеми контроллерами для рендеринга страниц, или если PostController отправляет в выделенный класс представления (назовите его PostView, если это делает его более понятным), и этот класс будет затем визуализировать определенный HTML-файл?

В основном, если это должен быть один класс View для всех контроллеров, который будет отображать любой html-файл, который ему сообщает контроллер, или если должно быть много классов View, по одному для каждой загрузки страницы.

Примечание: Я знаю, что много вопросов уже задавалось о MVC в PHP, но я не смог найти ответ на свой вопрос ни в одном из ответов.

Ответы [ 2 ]

0 голосов
/ 28 мая 2019

Немного о MVC:

В исходном паттерне MVC (представленном Trygve Reenskaug в 1979 году) контроллер обновляет модель, модель уведомляет представление об изменениях, ипредставление извлекает свои данные из него.Хотя шаблон был задуман для настольных приложений - каждая «триада» MVC связана с одним элементом управления в окне (кнопка, текстовое поле, флажок и т. Д.).Таким образом, к каждому элементу управления на экране был прикреплен MVC.

Поскольку в веб-приложениях шаг уведомления модели к представлению отсутствует (или не может быть), исходный шаблон можетне применять как есть к ним.Но наиболее похожий подход все же может быть относительно легко реализован: контроллер обновляет модель, представление извлекает из нее данные (независимо от контроллера).Я думаю, что это называется "Web MVC Model 2" .

Существует множество вариаций Web MVC.Вы используете тот, в котором контроллер играет роль посредника между моделью и представлением.Таким образом, контроллер является единственным компонентом, взаимодействующим с моделью.

Ответственность за представление:

Ответственность за компонент представления заключается в представлении логика - что вообще не должно приниматься контроллером.Помимо загрузки и рендеринга файлов шаблонов, этот тип логики включает подготовку данных, извлеченных из модели, для отображения .Результатом подготовки должен быть, предпочтительно, список значений примитивных типов (строки, логические значения, целые числа, массивы и т. Д.), Которые можно легко «внедрить» в файлы шаблонов в процессе загрузки и рендеринга.

Примеры логики представления:

Пример № 1: Если вы получите значение 123.45 (из столбцаamount таблицы revenues) из модели, логика представления будет состоять из форматирования ее в строку 123.45 USD для отображения в файле шаблона.

Пример # 2: Форматирование извлеченного значения даты от 28/05/2019 до 2019-05-28 с использованием фрагмента кода, подобного следующему:

$fetchedDateFromModel = '28/05/2019';
$time = strtotime($fetchedDateFromModel);
$formattedDate = date('Y-m-d', $time);

Тогда значение $formattedDate будет«внедрено» в файл шаблона.

Пример # 3: Установка логического значения на основе некоторых данных модели для использования в файле шаблона длярешить, должна ли кнопка («Получить бонус») быть активной или нет.

$paidAmount = 512.79; /* model data */
$isActiveGetBonusButton = false;

if ($paidAmount > 500) {
    $isActiveGetBonusButton = true;
}

Ответr (в отношении выбранного вами подхода MVC):

Используя экземпляр View во всех контроллерах, вы будете вынуждены выполнять определенную логику представления в каждом контроллере - перед передачей его результата (например,список подготовленных значений) к используемому экземпляру View, чтобы в дальнейшем просто «внедриться» в определенный файл шаблона.

Принимая во внимание, что если вы реализуете выделенный класс представления (например, * 1068)* - которые, предпочтительно, наследуют базовый класс View, содержащий метод render()) для класса контроллера (например, PostController) - таким образом, отношение 1: 1, но воспринимайте его как свободный!- вы можете передать данные, извлеченные из модели, в неподготовленной форме из контроллера в представление.Класс представления тогда правильно взял бы на себя ответственность за подготовку данных для отображения до фактической загрузки и рендеринга определенного файла шаблона.Например, выполнение всей конкретной логики представления.

Примечание: In "Web MVC Model 2" - где, в идеале, контроллер не знает компонента представления- приведенный выше аргумент более очевиден:

  • PostController просто обновляет модель (когда требуется шаг обновления);
  • PostView выбирает данные из модели, подготавливаетдля отображения и отображения (например, путем загрузки и рендеринга файла шаблона, например posts.html.twig).Другими словами, компонент представления сам выполняет всю логику представления.
0 голосов
/ 27 мая 2019

Лучший способ, IMO, - это чтобы класс View или Template выполнял всю работу, связанную с представлениями, одним простым способом: render(string $templateName, array $context = []).

Это позволяет легко расширять илисоздание адаптеров.Вы должны заставить свои контроллеры использовать этот метод.Если вы используете DI-контейнер в своей инфраструктуре, вы можете сделать TemplatingAwareInterface и реализовать это с чертой, которая позволяет вводить сеттер.Это добавит службу шаблонов при извлечении из контейнера службы.Таким образом, вы можете использовать $this->templating->render() в вашем контроллере, не делая его глобальным, не создавая службу шаблонов внутри контроллера и не внедряя контейнер в контроллер.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...