Flash messages
After saving a post the controller redirects the visitor to another page, and there is no one left to say "Post saved": the new request knows nothing about the previous one. A flash message solves this: the text is put into the session, and the next page shows it once and removes it.
Installation
The plugin lives in a separate package and uses the sessions from the previous lesson:
composer require laminas/laminas-mvc-plugin-flashmessengerAgree to inject the Laminas\Mvc\Plugin\FlashMessenger module into config/modules.config.php. There are no files to create: the plugin is available in controllers and view scripts right away.
Adding a message
A message is added in the action before the redirect:
// module/Blog/src/Controller/PostController.php
public function deleteAction()
{
$this->posts->delete((int) $this->params()->fromRoute('id'));
$this->flashMessenger()->addSuccessMessage('Post deleted.');
return $this->redirect()->toRoute('blog');
}The text is saved in the session and waits for the next request.
Rendering in the layout
A message can appear on any page, so it is rendered in the layout module/Application/view/layout/layout.phtml, before the content:
<!-- module/Application/view/layout/layout.phtml, inside body -->
<?= $this->flashMessenger()->render('success', ['alert', 'alert-success']) ?>
<main><?= $this->content ?></main>The first argument of render() is the kind of messages, the second the CSS classes for the list. Open /blog/delete/2: after the jump to /blog the line "Post deleted." appears above the list. Refresh the page — the message is gone.
The helper prints messages as a ul list; when there are no messages it prints nothing.
Kinds of messages
| Controller method | Kind name for render() |
|---|---|
addSuccessMessage($text) | success |
addErrorMessage($text) | error |
addWarningMessage($text) | warning |
addInfoMessage($text) | info |
addMessage($text) | default |
To show every kind, add one render() line per kind to the layout:
<!-- module/Application/view/layout/layout.phtml, inside body -->
<?= $this->flashMessenger()->render('success', ['alert', 'alert-success']) ?>
<?= $this->flashMessenger()->render('error', ['alert', 'alert-danger']) ?>A message after saving
The same technique is used in the add action from the forms lesson:
if ($form->isValid()) {
$post = new Post();
$post->exchangeArray($form->getData());
$this->posts->save($post);
$this->flashMessenger()->addSuccessMessage('Post saved.');
return $this->redirect()->toRoute('blog/view', ['id' => $post->id]);
}After submitting the form the visitor sees the post page with a confirmation at the top.
Common mistake
A flash message is meant for the next request. If you add one and return a ViewModel without redirecting, it does not appear on the current page but pops up unexpectedly on the next page the visitor opens. For a page shown right away, pass the text as an ordinary ViewModel variable, and use flash messages only together with redirect().