Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Сессии и flash-сообщения

Сессия — хранилище данных одного посетителя, которое сохраняется между его запросами: сайт помнит, что лежит в корзине или какой язык выбран. Flash-сообщение — запись в сессии, которая живёт до следующей страницы: с её помощью показывают «Статья сохранена» после перенаправления.

Где находится сессия

Сессия — компонент Yii::$app->session. Настраивать и открывать её не нужно: она запускается сама при первом обращении. Файлов для неё создавать не требуется — её используют в действиях и шаблонах.

Запись и чтение

// 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 "Вы открыли статей: $views";
}

Обновляйте страницу — число будет расти: значение хранится на сервере и привязано к браузеру посетителя. Второй аргумент get() — значение по умолчанию.

ВызовЧто делает
$session->set('key', $value)Записывает значение
$session->get('key', $default)Читает значение
$session->has('key')Проверяет, есть ли значение
$session->remove('key')Удаляет значение
$session->destroy()Удаляет все данные сессии

Flash-сообщение

После сохранения статьи действие перенаправляет посетителя, поэтому вывести сообщение сразу нельзя. Его записывают в сессию:

public function actionCreate()
{
    $post = new Post();
 
    if ($post->load(Yii::$app->request->post()) && $post->save()) {
        Yii::$app->session->setFlash('success', 'Статья сохранена.');
 
        return $this->redirect(['post/view', 'id' => $post->id]);
    }
 
    return $this->render('create', ['post' => $post]);
}

Первый аргумент — ключ сообщения, второй — текст.

Показ сообщения

В стандартном проекте макет views/layouts/main.php уже содержит строку <?= Alert::widget() ?>. Этот виджет (файл widgets/Alert.php) выводит сообщения с ключами success, error, danger, info и warning цветными блоками Bootstrap. Поэтому после сохранения статьи над содержимым страницы появится зелёная полоса «Статья сохранена.», а после обновления страницы она исчезнет.

В собственном макете без этого виджета сообщение выводят вручную:

<?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() возвращает текст и помечает сообщение прочитанным — на следующей странице его уже не будет.

Сессию браузер находит по cookie — небольшому значению, которое он хранит и присылает с каждым запросом. Свои cookie записывают через ответ, а читают через запрос:

Yii::$app->response->cookies->add(new \yii\web\Cookie([
    'name' => 'theme',
    'value' => 'dark',
]));
 
$theme = Yii::$app->request->cookies->getValue('theme', 'light');

Yii подписывает cookie ключом cookieValidationKey из config/web.php, поэтому посетитель не может подделать значение.

Частая ошибка

Flash-сообщение записывают перед перенаправлением, а не перед render(). Если после setFlash() сразу вывести шаблон, сообщение появится и на этой странице, и ещё раз на следующей. Правило простое: успешное действие заканчивается парой setFlash() и redirect().

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.