Сообщения после действия
После сохранения статьи контроллер перенаправляет посетителя на другую страницу, и сказать «Статья сохранена» уже некому: новый запрос ничего не знает о прошлом. Flash-сообщение решает эту задачу: текст кладут в сессию, а следующая страница показывает его один раз и удаляет.
Установка
Помощник живёт в отдельном пакете и использует сессии из прошлого урока:
composer require laminas/laminas-mvc-plugin-flashmessengerСогласитесь вписать модуль Laminas\Mvc\Plugin\FlashMessenger в config/modules.config.php. Создавать файлы не нужно: помощник сразу доступен в контроллерах и шаблонах.
Запись сообщения
Сообщение добавляют в действии перед перенаправлением:
// module/Blog/src/Controller/PostController.php
public function deleteAction()
{
$this->posts->delete((int) $this->params()->fromRoute('id'));
$this->flashMessenger()->addSuccessMessage('Статья удалена.');
return $this->redirect()->toRoute('blog');
}Текст сохраняется в сессии и ждёт следующего запроса.
Вывод в макете
Сообщение может появиться на любой странице, поэтому выводят его в макете module/Application/view/layout/layout.phtml, перед содержимым:
<!-- module/Application/view/layout/layout.phtml, внутри body -->
<?= $this->flashMessenger()->render('success', ['alert', 'alert-success']) ?>
<main><?= $this->content ?></main>Первый аргумент render() — вид сообщений, второй — классы CSS для списка. Откройте /blog/delete/2: после перехода на /blog над списком появится строка «Статья удалена.». Обновите страницу — сообщение исчезнет.
Помощник выводит сообщения списком ul; если сообщений нет, он не выводит ничего.
Виды сообщений
| Метод в контроллере | Имя вида для render() |
|---|---|
addSuccessMessage($text) | success |
addErrorMessage($text) | error |
addWarningMessage($text) | warning |
addInfoMessage($text) | info |
addMessage($text) | default |
Чтобы показывать все виды, добавьте в макет по строке render() на каждый:
<!-- module/Application/view/layout/layout.phtml, внутри body -->
<?= $this->flashMessenger()->render('success', ['alert', 'alert-success']) ?>
<?= $this->flashMessenger()->render('error', ['alert', 'alert-danger']) ?>Сообщение после сохранения
Тот же приём используют в действии add из урока о формах:
if ($form->isValid()) {
$post = new Post();
$post->exchangeArray($form->getData());
$this->posts->save($post);
$this->flashMessenger()->addSuccessMessage('Статья сохранена.');
return $this->redirect()->toRoute('blog/view', ['id' => $post->id]);
}После отправки формы посетитель увидит страницу статьи с подтверждением наверху.
Частая ошибка
Flash-сообщение рассчитано на следующий запрос. Если добавить его и вернуть ViewModel без перенаправления, на текущей странице оно не появится, зато неожиданно всплывёт на следующей, куда перейдёт посетитель. Для страницы, которая показывается сразу, передавайте текст обычной переменной в ViewModel, а flash-сообщения используйте только вместе с redirect().