Sessions and flash messages
A session is a storage for the data of one visitor that survives between their requests: the site remembers what is in the cart or which language is chosen. A flash message is a session record that lives until the next page: it is used to show "Post saved" after a redirect.
Where the session is
The session is the Yii::$app->session component. It needs no setup or opening: it starts on first access. No files have to be created for it; it is used in actions and views.
Writing and reading
// controllers/PostController.php
public function actionView(int $id): string
{
$session = Yii::$app->session;
$session->set('lastPostId', $id);
$views = $session->get('views', 0) + 1;
$session->set('views', $views);
return "Posts you have opened: $views";
}Refresh the page and the number grows: the value is stored on the server and tied to the visitor's browser. The second argument of get() is the default value.
| Call | What it does |
|---|---|
$session->set('key', $value) | Writes a value |
$session->get('key', $default) | Reads a value |
$session->has('key') | Checks whether a value exists |
$session->remove('key') | Removes a value |
$session->destroy() | Removes all session data |
A flash message
After saving a post the action redirects the visitor, so a message cannot be printed right away. It is written to the session:
public function actionCreate()
{
$post = new Post();
if ($post->load(Yii::$app->request->post()) && $post->save()) {
Yii::$app->session->setFlash('success', 'Post saved.');
return $this->redirect(['post/view', 'id' => $post->id]);
}
return $this->render('create', ['post' => $post]);
}The first argument is the message key, the second is the text.
Showing the message
In the standard project the layout views/layouts/main.php already contains the line <?= Alert::widget() ?>. This widget (the file widgets/Alert.php) prints messages with the keys success, error, danger, info and warning as coloured Bootstrap blocks. So after a post is saved a green bar "Post saved." appears above the page content, and after a refresh it is gone.
In your own layout without this widget the message is printed by hand:
<?php
// views/layouts/main.php
use yii\helpers\Html;
?>
<?php if (Yii::$app->session->hasFlash('success')): ?>
<div class="alert alert-success">
<?= Html::encode(Yii::$app->session->getFlash('success')) ?>
</div>
<?php endif; ?>getFlash() returns the text and marks the message as read, so it is gone on the next page.
Cookies
The browser finds its session by a cookie, a small value it stores and sends with every request. Your own cookies are written through the response and read through the request:
Yii::$app->response->cookies->add(new \yii\web\Cookie([
'name' => 'theme',
'value' => 'dark',
]));
$theme = Yii::$app->request->cookies->getValue('theme', 'light');Yii signs cookies with the cookieValidationKey from config/web.php, so a visitor cannot forge a value.
Common mistake
A flash message is set before a redirect, not before render(). If you render a view right after setFlash(), the message appears on this page and once more on the next one. The rule is simple: a successful action ends with the pair setFlash() and redirect().