Идёт обновление сайта. Несколько дней возможны сбои в оформлении и переводах. Документация работает — если страница выглядит сломанной, обновите её позже.

Документация
L Laravel L intervention/image
Войти
Главная Laravel 10.x HTTP-сессия

HTTP-сессия

10.x 7 мар 2026 г.

#Введение

Поскольку HTTP-приложения являются безсостоянием, сессии предоставляют способ хранения информации о пользователе между несколькими запросами. Эта информация обычно сохраняется в постоянном хранилище или бэкенде, к которому можно получить доступ из последующих запросов.

Laravel поставляется с разнообразными бэкендами для сессий, доступ к которым осуществляется через выразительный, унифицированный API. Поддержка популярных бэкендов, таких как Memcached, Redis и базы данных, включена.

#Настройка

Файл конфигурации сессий вашего приложения находится в config/session.php. Обязательно ознакомьтесь с доступными в этом файле опциями. По умолчанию Laravel настроен на использование драйвера сессий file, который подходит для многих приложений. Если ваше приложение будет работать за балансировщиком нагрузки на нескольких веб-серверах, следует выбрать централизованное хранилище, доступное для всех серверов, например Redis или базу данных.

Опция конфигурации driver определяет, где будут храниться данные сессии для каждого запроса. Laravel поставляется с несколькими отличными драйверами из коробки:

  • file — сессии хранятся в storage/framework/sessions.
  • cookie — сессии хранятся в защищённых, зашифрованных cookie.
  • database — сессии хранятся в реляционной базе данных.
  • memcached / redis — сессии хранятся в одном из этих быстрых кэш-хранилищ.
  • dynamodb — сессии хранятся в AWS DynamoDB.
  • array — сессии хранятся в PHP-массиве и не сохраняются между запросами.
Примечание

Драйвер array в основном используется при тестировании и не сохраняет данные, хранящиеся в сессии.

#Требования к драйверу

#База данных

При использовании драйвера сессий database необходимо создать таблицу для хранения записей сессий. Пример объявления схемы Schema для таблицы приведён ниже:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::create('sessions', function (Blueprint $table) {
    $table->string('id')->primary();
    $table->foreignId('user_id')->nullable()->index();
    $table->string('ip_address', 45)->nullable();
    $table->text('user_agent')->nullable();
    $table->text('payload');
    $table->integer('last_activity')->index();
});

Вы можете использовать Artisan-команду session:table для генерации этой миграции. Подробнее о миграциях баз данных читайте в полном руководстве по миграциям:

php artisan session:table

php artisan migrate

#Redis

Перед использованием сессий Redis с Laravel необходимо установить расширение PhpRedis через PECL или пакет predis/predis (~1.0) через Composer. Для дополнительной информации о настройке Redis обратитесь к документации Laravel по Redis.

Примечание

В файле конфигурации session опция connection может использоваться для указания, какое соединение Redis будет использоваться для сессий.

#Работа с сессией

#Получение данных

В Laravel есть два основных способа работы с данными сессии: глобальный помощник session и через экземпляр Request. Сначала рассмотрим доступ к сессии через экземпляр Request, который можно указать в качестве типа параметра в замыкании маршрута или методе контроллера. Помните, что зависимости методов контроллера автоматически внедряются через service container Laravel:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\View\View;

class UserController extends Controller
{
    /**
     * Показать профиль указанного пользователя.
     */
    public function show(Request $request, string $id): View
    {
        $value = $request->session()->get('key');

        // ...

        $user = $this->users->find($id);

        return view('user.profile', ['user' => $user]);
    }
}

При получении элемента из сессии вы также можете передать значение по умолчанию в виде второго аргумента методу get. Это значение будет возвращено, если указанный ключ не существует в сессии. Если вы передадите замыкание в качестве значения по умолчанию методу get и запрошенный ключ отсутствует, замыкание будет выполнено, а его результат возвращён:

$value = $request->session()->get('key', 'default');

$value = $request->session()->get('key', function () {
    return 'default';
});

#Глобальный помощник session

Вы также можете использовать глобальную PHP-функцию session для получения и сохранения данных в сессии. Если вызвать помощник session с одним строковым аргументом, он вернёт значение по этому ключу. Если вызвать с массивом пар ключ/значение, эти значения будут сохранены в сессии:

Route::get('/home', function () {
    // Получить данные из сессии...
    $value = session('key');

    // Указать значение по умолчанию...
    $value = session('key', 'default');

    // Сохранить данные в сессии...
    session(['key' => 'value']);
});
Примечание

Практической разницы между использованием сессии через экземпляр HTTP-запроса и глобальным помощником session почти нет. Оба способа тестируются с помощью метода assertSessionHas, доступного во всех ваших тестах.

#Получение всех данных сессии

Если нужно получить все данные сессии, используйте метод all:

$data = $request->session()->all();

#Получение части данных сессии

Методы only и except позволяют получить подмножество данных сессии:

$data = $request->session()->only(['username', 'email']);

$data = $request->session()->except(['username', 'email']);

#Проверка наличия элемента в сессии

Чтобы определить, присутствует ли элемент в сессии, можно использовать метод has. Метод has возвращает true, если элемент присутствует и не равен null:

if ($request->session()->has('users')) {
    // ...
}

Чтобы проверить, существует ли элемент в сессии, даже если его значение null, используйте метод exists:

if ($request->session()->exists('users')) {
    // ...
}

Чтобы проверить, отсутствует ли элемент в сессии, используйте метод missing. Метод missing возвращает true, если элемент отсутствует:

if ($request->session()->missing('users')) {
    // ...
}

#Сохранение данных

Для сохранения данных в сессии обычно используют метод put экземпляра запроса или глобальный помощник session:

// Через экземпляр запроса...
$request->session()->put('key', 'value');

// Через глобальный помощник "session"...
session(['key' => 'value']);

#Добавление значения в массив сессии

Метод push позволяет добавить новое значение в сессионный элемент, который является массивом. Например, если ключ user.teams содержит массив названий команд, можно добавить новое значение так:

$request->session()->push('user.teams', 'developers');

#Получение и удаление элемента

Метод pull одновременно получает и удаляет элемент из сессии:

$value = $request->session()->pull('key', 'default');

#Увеличение и уменьшение значений сессии

Если в сессии хранится целое число, которое нужно увеличить или уменьшить, используйте методы increment и decrement:

$request->session()->increment('count');

$request->session()->increment('count', $incrementBy = 2);

$request->session()->decrement('count');

$request->session()->decrement('count', $decrementBy = 2);

#Временные данные (Flash Data)

Иногда нужно сохранить данные в сессии только для следующего запроса. Для этого используется метод flash. Данные, сохранённые таким образом, доступны сразу и в следующем HTTP-запросе, после чего удаляются. Flash-данные полезны для кратковременных сообщений о статусе:

$request->session()->flash('status', 'Task was successful!');

Если нужно сохранить flash-данные на несколько запросов, используйте метод reflash, который продлевает срок хранения всех flash-данных на ещё один запрос. Если нужно сохранить только определённые flash-данные, используйте метод keep:

$request->session()->reflash();

$request->session()->keep(['username', 'email']);

Чтобы сохранить flash-данные только для текущего запроса, используйте метод now:

$request->session()->now('status', 'Task was successful!');

#Удаление данных

Метод forget удаляет элемент из сессии. Чтобы удалить все данные сессии, используйте метод flush:

// Удалить один ключ...
$request->session()->forget('name');

// Удалить несколько ключей...
$request->session()->forget(['name', 'status']);

$request->session()->flush();

#Регенирация ID сессии

Регенирация ID сессии часто выполняется для предотвращения атак типа session fixation на ваше приложение.

Laravel автоматически регенерирует ID сессии при аутентификации, если вы используете один из стартовых наборов приложений Laravel или Laravel Fortify; однако, если нужно сделать это вручную, используйте метод regenerate:

$request->session()->regenerate();

Если нужно регенерировать ID сессии и одновременно удалить все данные сессии, используйте метод invalidate:

$request->session()->invalidate();

#Блокировка сессии

Внимание

Для использования блокировки сессии ваше приложение должно использовать драйвер кэша, поддерживающий атомарные блокировки. В настоящее время такими драйверами являются memcached, dynamodb, redis, database, file и array. Кроме того, нельзя использовать драйвер сессий cookie.

По умолчанию Laravel позволяет выполнять запросы с одной и той же сессией одновременно. Например, если вы используете JavaScript HTTP-библиотеку для отправки двух запросов к вашему приложению, они будут выполняться параллельно. Для многих приложений это не проблема; однако в некоторых случаях при одновременных запросах к разным конечным точкам приложения, которые записывают данные в сессию, может возникнуть потеря данных.

Для решения этой проблемы Laravel предоставляет функциональность, позволяющую ограничить одновременное выполнение запросов для одной сессии. Чтобы начать, просто добавьте метод block к определению маршрута. В этом примере входящий запрос к /profile получит блокировку сессии. Пока блокировка удерживается, все входящие запросы к /profile или /order с тем же ID сессии будут ждать завершения первого запроса перед продолжением:

Route::post('/profile', function () {
    // ...
})->block($lockSeconds = 10, $waitSeconds = 10)

Route::post('/order', function () {
    // ...
})->block($lockSeconds = 10, $waitSeconds = 10)

Метод block принимает два необязательных аргумента. Первый аргумент, принимаемый методом block, — это максимальное количество секунд, в течение которых блокировка сессии будет удерживаться перед её освобождением. Если запрос завершится раньше этого времени, блокировка будет освобождена ранее.

Второй аргумент метода block — это количество секунд, которое запрос должен ждать при попытке получить блокировку сессии. Будет выброшено исключение Illuminate\Contracts\Cache\LockTimeoutException, если запрос не сможет получить блокировку сессии в течение указанного количества секунд.

Если аргументы не переданы, блокировка будет удерживаться максимум 10 секунд, а запросы будут ждать максимум 10 секунд при попытке получить блокировку:

Route::post('/profile', function () {
    // ...
})->block()

#Добавление пользовательских драйверов сессий

#Реализация драйвера

Если ни один из существующих драйверов сессий не подходит для вашего приложения, Laravel позволяет написать собственный обработчик сессий. Ваш пользовательский драйвер должен реализовывать встроенный в PHP интерфейс SessionHandlerInterface. Этот интерфейс содержит всего несколько простых методов. Пример заглушки реализации для MongoDB выглядит так:

<?php

namespace App\Extensions;

class MongoSessionHandler implements \SessionHandlerInterface
{
    public function open($savePath, $sessionName) {}
    public function close() {}
    public function read($sessionId) {}
    public function write($sessionId, $data) {}
    public function destroy($sessionId) {}
    public function gc($lifetime) {}
}
Примечание

Laravel не поставляется с директорией для ваших расширений. Вы можете разместить их где угодно. В этом примере мы создали директорию Extensions для хранения MongoSessionHandler.

Поскольку назначение этих методов не всегда очевидно, кратко опишем, что делает каждый из них:

  • Метод open обычно используется в файловых системах хранения сессий. Поскольку Laravel поставляется с драйвером file, вам редко нужно что-то писать в этот метод. Его можно оставить пустым.
  • Метод close, как и open, обычно можно игнорировать. Для большинства драйверов он не нужен.
  • Метод read должен возвращать строковое представление данных сессии, связанных с данным $sessionId. Не нужно выполнять сериализацию или кодирование — Laravel сделает это за вас.
  • Метод write должен записывать переданную строку $data, связанную с $sessionId, в постоянное хранилище, например MongoDB или другое. Сериализацию выполнять не нужно — Laravel уже позаботился об этом.
  • Метод destroy должен удалять данные, связанные с $sessionId, из постоянного хранилища.
  • Метод gc должен удалять все данные сессий, старше указанного $lifetime (UNIX-времени). Для систем с автоматическим истечением срока, таких как Memcached и Redis, этот метод можно оставить пустым.

#Регистрация драйвера

После реализации драйвера зарегистрируйте его в Laravel. Чтобы добавить дополнительные драйверы в механизм хранения сессий Laravel, используйте метод extend, предоставляемый Session фасад. Вызывать метод extend нужно из метода boot сервис-провайдера. Это можно сделать в существующем App\Providers\AppServiceProvider или создать новый провайдер:

<?php

namespace App\Providers;

use App\Extensions\MongoSessionHandler;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\ServiceProvider;

class SessionServiceProvider extends ServiceProvider
{
    /**
     * Регистрация сервисов приложения.
     */
    public function register(): void
    {
        // ...
    }

    /**
     * Загрузка сервисов приложения.
     */
    public function boot(): void
    {
        Session::extend('mongo', function (Application $app) {
            // Вернуть реализацию SessionHandlerInterface...
            return new MongoSessionHandler;
        });
    }
}

После регистрации драйвера сессий вы можете использовать драйвер mongo в файле конфигурации config/session.php.