Формирование HTML во фреймворках — отдельная тема. Не запрещено создавать HTML напрямую в виде строки, но такой способ перестает работать на реальных сайтах, где HTML одной страницы — это сотни, а то и тысячи строк.
Рассмотрим следующий пример:
<?php
$app->get('/courses/{name}', function ($request, $response, array $args) use ($courses) {
$slug = $args['name'];
$course = $courses[$slug];
return $response->write("<h1>{$course->name}</h1>")
->write("<div>{$course->body}</div>");
});
У такого подхода есть следующие недостатки:
- Он небезопасен и может привести к взлому. Подробнее эта тема рассматривается в конце курса
- С ростом количества HTML поддерживать такой код станет практически невозможно, так как неудобно анализировать и редактировать
- В таком коде будут возникать постоянные проблемы с необходимостью экранировать одинарные или двойные кавычки
- В таком коде легко допустить ошибку в HTML и сложно ее обнаружить
- В типичных сайтах большая часть HTML общая для разных страниц. Выделить ее с помощью подхода выше сложно
Для решения подобных задач придумали шаблонизаторы — специализированные библиотеки, которые позволяют описывать шаблон отдельно от остальной части кода. Мы будем использовать slim/php-view, который установили ранее.
Измените настройку Slim в начале файла public/index.php так, как показано в примере:
<?php
// Контейнеры в этом курсе не рассматриваются (это тема связанная с самим ООП), но если интересно, то посмотрите DI Container
use Slim\Factory\AppFactory;
use DI\Container;
$container = new Container();
$container->set('renderer', function () {
// Параметром передается базовая директория, в которой будут храниться шаблоны
return new \Slim\Views\PhpRenderer(__DIR__ . '/../templates');
});
$app = AppFactory::createFromContainer($container);
$app->addErrorMiddleware(true, true, true);
В этих строчках происходит подключение шаблонизатора к Слиму с помощью DI Container. Наши шаблоны будут храниться в директории templates в корне проекта.
Далее добавьте еще один обработчик:
<?php
$app->get('/users/{id}', function ($request, $response, $args) {
$params = ['id' => $args['id'], 'nickname' => 'user-' . $args['id']];
// Указанный путь считается относительно базовой директории для шаблонов, заданной на этапе конфигурации
// $this доступен внутри анонимной функции благодаря https://php.net/manual/ru/closure.bindto.php
// $this в Slim это контейнер зависимостей
return $this->get('renderer')->render($response, 'users/show.phtml', $params);
});
Метод render()
выполняет рендеринг указанного шаблона и добавляет результат в ответ. Сама функция принимает на вход три параметра:
- Объект ответа
- Путь до нужного шаблона внутри директории templates
- Набор параметров, которые будут доступны внутри шаблона. Сюда можно передавать все что угодно
Добавьте файл templates/users/show.phtml со следующим содержимым:
<h1>Hello, <?= $id ?></h1>
Расширение phtml используют, когда хотят показать, что внутри файла содержится шаблон на PHP. В остальном файл рассматривается как обычный файл с кодом на PHP.
Теперь откройте браузер и попробуйте загрузить страницу http://localhost:8080/users/nick.
curl localhost:8080/users/nick
<h1>Hello, nick</h1>
Вместо кода <?= $id ?>
на экране появилось значение переменной $id
. Это произошло, потому что шаблонизатор берет массив $params
, который передается третьим параметром в метод render()
и создает внутри шаблона локальную переменную на каждый ключ этого массива. Причем имя переменной и ключа совпадают.
Этот принцип работает всегда. Если нужно вывести данные на странице, то их добавляют в массив $params
и обращаются к ним в шаблоне через переменные.
Этой тактики следует придерживаться и для суперглобальных массивов. По понятным причинам их можно использовать напрямую:
<h1><?= $_GET['name'] ?></h1>
Но делать так нельзя. Такой код значительно сложнее в отладке и потенциально опасен. Подробнее об этом дальше по курсу.
Собирая все вместе
Теперь, когда мы добавили поддержку шаблонов во фреймворк, появляется способ создавать нетривиальные сайты. Ниже пример обработчика и шаблона для вывода курсов:
Обработчик
<?php
$app->get('/courses', function ($request, $response) use ($courses) {
$params = [
'courses' => $courses
];
return $this->get('renderer')->render($response, 'courses/index.phtml', $params);
});
Шаблон
<table>
<?php foreach ($courses as $course): ?>
<tr>
<td>
<?= $course['id'] ?>
</td>
<td>
<?= $course['name'] ?>
</td>
</tr>
<?php endforeach ?>
</table>
<!-- END -->
Самостоятельная работа
-
Измените настройку Slim в начале файла public/index.php как описано в примере из теории. И добавьте обработчик для просмотра страницы пользователя (следующий после настройки пример)
-
Создайте для него шаблон templates/users/show.phtml. Выведите в нем идентификатор пользователя и никнейм пользователя
-
Выполните запрос к странице /users/5
Попробуйте поменять число.
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.