Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

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-flashmessenger

Agree 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 methodKind 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().

Thanks for reading!

Donate to the site — we work hard for you.