Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

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.

CallWhat 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().

Thanks for reading!

Donate to the site — we work hard for you.