View в MVC

View в MVC

Сегодня мы сделаем компонент View, то самое “V” в архитектуре MVC. View – это представление, то есть та часть программы, которая формирует то, что видит пользователь.

В случае приложения на языке PHP, в подавляющем большинстве случаев представление занимается формированием HTML-кода. Вообще, это довольно простая часть кода, которой даётся только имя шаблона и список переменных, которые в этот шаблон нужно подставить.

Итак, давайте рассмотрим простейший пример и создадим для начала только шаблон. Путь до него будет следующим: templates/main/main.php

Шаблон main.php

Давайте запишем в него HTML-код для нашей будущей странички
templates/main/main.php

Код доступен только после покупки курса ООП в PHP.

Теперь давайте откроем наш контроллер MainController и изменим его метод main()
src/MyProject/Controllers/MainController.php

Код доступен только после покупки курса ООП в PHP.

Теперь откроем http://myproject.loc/ и полюбуемся результатом:

Результат вывода шаблона

Для начала давайте немного облегчим шаблон и вынесем стили в отдельный файл. Для этого в папке www создадим файл styles.css.
www/styles.css

Код доступен только после покупки курса ООП в PHP.

Теперь подключим этот файл со стилями в шаблоне:

Код доступен только после покупки курса ООП в PHP.

И снова убедимся, что всё работает.
Отображение при подключении внешних стилей

Давайте теперь попробуем передавать в шаблон переменные. Вместо явно заданных статей сделаем переменную со статьями:
src/MyProject/Controllers/MainController.php

Код доступен только после покупки курса ООП в PHP.

А теперь выведем эти статьи в шаблоне:
templates/main/main.php

Код доступен только после покупки курса ООП в PHP.

Если нам понадобится в другом контроллере или другом экшне добавить логику для работы с шаблонами, нам снова придется перечислять список переменных, а затем писать include с указанием полного пути для шаблона. Звучит не очень хорошо. Поэтому мы просто вынесем логику с подключением нужного шаблона в отдельный класс.

Создадим класс View.php по пути src/MyProject/View/View.php
Класс View

В конструкторе этого класса мы будем принимать путь до папки с шаблонами:
src/MyProject/View/View.php

Код доступен только после покупки курса ООП в PHP.

Помимо этого давайте добавим метод, в который будем передавать имя конкретного шаблона и массив с переменными.

Код доступен только после покупки курса ООП в PHP.

Функция extract извлекает массив в переменные. То есть она делает следующее: в неё передаётся массив ['key1' => 1, 'key2' => 2], а после её вызова у нас имеются переменные $key1 = 1 и $key2 = 2.

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

Пришло время опробовать этот код в нашем контроллере. Создадим новый объект View в конструкторе контроллера, а затем внутри экшена вызовем renderHtml().
src/MyProject/Controllers/MainController.php

Код доступен только после покупки курса ООП в PHP.

Теперь мы можем снова открыть сайт, и убедиться, что всё прекрасно работает.

Буфер вывода

В тот момент, когда мы подключаем файл c HTML-кодом, либо пишем в PHP-коде echo, либо совершаем какой-либо другой вывод данных, эти данные начинают сразу передаваться в поток вывода. И если что-то пойдёт не так, мы не сможем вернуть этот вывод и вывести вместо него какую-нибудь ошибку. Но в PHP есть возможность весь этот поток вывода положить во временный буфер вывода. Выглядит его использование следующим образом:
src/MyProject/View/View.php

Код доступен только после покупки курса ООП в PHP.

Если вы сейчас попробуете запустить наш скрипт, то увидите пустую страницу. Дело в том, что все данные, которые должны были быть переданы в поток вывода, оказались в переменной $buffer.
Для того, чтобы передать эти данные в поток вывода, достаточно только вывести переменную $buffer.
src/MyProject/View/View.php

Код доступен только после покупки курса ООП в PHP.

Откройте страничку снова, и убедитесь, что всё вернулось на свои места.

Так в чём же профит? А профит в том, что мы можем обрабатывать ошибки, возникшие в процессе работы с шаблоном. Пока мы с вами не знакомы с понятием «Исключения», давайте предположим, что у нас при подключении шаблона произошла какая-то ошибка. Тогда мы могли бы обработать эту ошибку и не выводить пользователю неправильно отрисованный шаблон. Мы могли бы сделать что-то типа такого:
src/MyProject/View/View.php

Код доступен только после покупки курса ООП в PHP.

Чуть позже мы вернёмся к обработке возможных ошибок, когда познакомимся с исключениями. А пока оставим этот код в таком состоянии:
src/MyProject/View/View.php

Код доступен только после покупки курса ООП в PHP.

Реиспользование шаблонов

Давайте в наш контроллер вернём экшн из прошлых уроков, который выводил приветствие.
src/MyProject/Controllers/MainController.php

Код доступен только после покупки курса ООП в PHP.

Давайте изменим его, чтобы он работал через шаблон.

Код доступен только после покупки курса ООП в PHP.

Ну и создадим сам шаблон для него.
templates/main/hello.php

Код доступен только после покупки курса ООП в PHP.

Давайте теперь перейдём по адресу http://myproject.loc/hello/username и увидим, что всё прекрасно сработало:

Рендеринг другого шаблона

А теперь внимательно присмотритесь к нашим двум получившимся шаблонам. Согласитесь, у них всё абсолютно одинаковое, кроме текста, который мы выводим на странице. Давайте это исправим! Всё, что выше нашего контента – вынесем в один файл, всё что ниже – в другой. А в самих наших шаблонах будем эти два файла подключать.

Итак, выносим верхнюю часть (так называемую шапку сайта - хедер) в новый файл templates/header.php
templates/header.php

Код доступен только после покупки курса ООП в PHP.

Затем выносим нижнюю часть (называемую футером или подвалом) в файл templates/footer.php
templates/footer.php

Код доступен только после покупки курса ООП в PHP.

После чего редактируем наши шаблоны:
templates/main/main.php

Код доступен только после покупки курса ООП в PHP.

templates/main/hello.php

Код доступен только после покупки курса ООП в PHP.

Должна получиться вот такая структура в шаблонах:
Структура папки с шаблонами

После этого заходим на странички http://myproject.loc/hello/username и http://myproject.loc/ и радуемся результату :)

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

Давайте повторим последовательность шагов, которые необходимо сделать для добавления новой странички:

  1. Добавляем экшн в контроллер (либо создаём ещё и новый контроллер);
  2. Добавляем для него роут в routes.php;
  3. Описываем логику внутри экшена и в конце вызываем у компонента view метод renderHtml();
  4. Создаём шаблон для вывода результата.

Вот и весь View.