Шаблоны сайта содержат множество внутренних ссылок: от меню до кнопок и форм. До сих пор мы формировали эти ссылки там, где они нам нужны:
<form action="/users/<?= $user['id'] ?>" method="post">
<input type="hidden" name="_METHOD" value="DELETE">
<input type="submit" value="Remove">
</form>
Так же ссылки строятся и в обработчиках, например, при редиректах:
<?php
$app->post('/users', function ($request, $response) use ($repo) {
$validator = new Validator();
$user = $request->getParsedBodyParam('user');
$errors = $validator->validate($user);
if (count($errors) === 0) {
$repo->save($user);
// Тут формируется ссылка
return $response->withRedirect("/user/{$user['id']}");
}
// остальной код
});
В примерах выше формирование ссылки зашито прямо в то место, где она используется. Такой способ формирования ссылок потенциально опасен. Например, если маршрут изменится с /users/{id}
на /u/{id}
, придется пройтись по всем шаблонам и изменить все ссылки /users/<?= $user['id'] ?>
на /u/<?= $user['id'] ?>
.
Если этот маршрут удалить, то сайт продолжит работать, но ссылки начнут вести на страницы 404. Лучше, если страницы с такими ссылками начнут выдавать ошибки. Тогда выявить подобные ссылки будет просто.
Для решения этой задачи придумали именованные маршруты. Каждому маршруту фреймворка присваивается имя, которое затем можно использовать при построении конкретной ссылки:
<?php
$app = AppFactory::create();
// Метод `setName` задает имя маршрута. Затем это имя используется для формирования нужного адреса. Ниже пример того, как это сделать:
$app->get('/users', function ($request, $response) {
// код обработчика
})->setName('users');
$app->get('/users/{id}', function ($request, $response) {
// код обработчика
})->setName('user');
// Получаем роутер — объект, отвечающий за хранение и обработку маршрутов
$router = $app->getRouteCollector()->getRouteParser();
// Не забываем прокинуть его в обработчик
$app->get('/', function ($request, $response) use ($router) {
// в функцию передается имя маршрута, а она возвращает url
$router->urlFor('users'); // /users
$router->urlFor('user', ['id' => 4]); // /users/4
// остальной код
});
В реальных приложениях ссылки формируются во многих частях приложениях:
- В шаблонах
- В обработчиках (при редиректах)
- В письмах
Поэтому большинство фреймворков предоставляют готовую функцию, которую можно использовать везде, где формируются ссылки. PHP-View, который мы используем, не добавляет этот метод в шаблоны. Но это возможно в Twig-View. В последнем ссылки в шаблонах строятся так:
{% extends "layout.html" %}
{% block body %}
<h1>User List</h1>
<ul>
<li><a href="{{ url_for('profile', { 'name': 'andrew' }) }}">Andrew</a></li>
</ul>
{% endblock %}
Самостоятельная работа
- Сделайте все маршруты именованными
- Сделайте так, чтобы в обработчиках обращение ко всем маршрутам было через их имена
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.