{{TOC}} {{DOCVER 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51, 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=cdc24ba7426c5b11eb4d050706bd78c3ea4913cc 19.06.2016 20:08:01, 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11}} == Введение == HTTP-приложения не имеют //состояний//. Сессии - способ сохранения информации о пользователе между отдельными запросами. Laravel поставляется со множеством различных механизмов сессий, доступных через единый выразительный API. Из коробки поддерживаются такие популярные системы, как ((http://memcached.org/ Memcached)), ((http://redis.io/ Redis)) и СУБД. === Настройка === Настройки сессии содержатся в файле %%(t)config/session.php%%. Обязательно просмотрите параметры, доступные вам в этом файле. По умолчанию Laravel использует драйвер сессий **file**, который подходит для большинства приложений. Для увеличения производительности сессий в продакшне вы можете использовать драйверы **memcached** или **redis**. Настройки //драйвера// определяют, где будут храниться данные сессии для каждого запроса. Laravel поставляется с целым набором замечательных драйверов: * **file** - данные хранятся в %%(t)storage/framework/sessions%%. * **cookie** - данные хранятся в виде зашифрованных ((docs/v5/requests#cookie+s)). * **database** - хранение данных в реляционной БД. * **memcached** / **redis** - для хранения используются эти быстрые кэширующие хранилища. * **array** - сессии хранятся в виде PHP-массивов и не будут сохраняться между запросами. .(alert) **Внимание:** драйвер **array** обычно используется во время ((docs/v5/testing тестирования)), так как он на самом деле не сохраняет данные для последующих запросов. === Требования для драйверов === **Database** При использовании драйвера сессий **database** вам необходимо создать таблицу для хранения данных сессии. Ниже - пример такого объявления с помощью ((docs/v5/schema конструктора таблиц)): %% Schema::create('sessions', function ($table) { $table->string('id')->unique(); $table->integer('user_id')->nullable(); $table->string('ip_address', 45)->nullable(); $table->text('user_agent')->nullable(); $table->text('payload'); $table->integer('last_activity'); }); %% Для создания этой миграции вы можете использовать Artisan-команду %%(sh)session:table%%: %%(sh) php artisan session:table php artisan migrate %% **Redis** Чтобы использовать сессии Redis в Laravel, необходимо установить пакет %%(t)predis/predis%% (~1.0) с помощью Composer. Вы можете настроить подключения Redis в файле настроек %%(t)database%%. А в файле %%(t)session%% в параметре %%(t)connection%% можно указать конкретное подключение Redis для сессии. %%(DOCNEW 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=cdc24ba7426c5b11eb4d050706bd78c3ea4913cc 19.06.2016 20:08:01, 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11) === Другие рекомендации для сессий === Laravel использует внутренний ключ сессий %%(t)flash%%, поэтому нельзя добавлять элемент с таким именем в сессию. Если вы хотите шифровать все хранимые данные сессий, установите значение параметра %%(t)encrypt%% равное %%(t)true%%. %% %%(DOCNEW 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11) .(alert) **Внимание:** При использовании драйвера сессий **cookie**, никогда не удаляйте посредника %%(t)EncryptCookie%% из вашего HTTP-ядра. Если вы это сделаете, ваше приложение станет уязвимым для удалённого внедрения кода. %% == Использование сессий == === Получение данных === В Laravel есть два основных способа работы с данными сессии: с помощью глобального вспомогательного метода %%session()%% и через экземпляр %%(t)Request%%. Сначала давайте обратимся к сессии через экземпляр %%(t)Request%%, который может быть указан в качестве зависимости в методе контроллера. Учтите, зависимости метода контроллера автоматически внедряются при помощи ((/docs/v5/container сервис-контейнера)) Laravel: %% session()->get('key'); // } } %% При получении значения из сессии, вы можете передать значение по умолчанию вторым аргументом метода %%get()%%. Это значение будет возвращено, если указанного ключа нет в сессии. Если вы передадите в метод замыкание в качестве значения по умолчанию, и запрашиваемого ключа не существует, то будет выполняться это замыкание и возвращаться его результат: %% $value = $request->session()->get('key', 'default'); $value = $request->session()->get('key', function () { return 'default'; }); %% **Глобальный вспомогательный метод %%session()%%** Также вы можете использовать глобальную PHP-функцию %%session()%% для извлечения и помещения данных в сессию. При вызове %%session()%% с одним строковым аргументом, метод вернёт значение ключа этой сессии. При вызове %%session()%% с массивом пар ключ/значение, эти значения будут сохранены в сессии: %% Route::get('home', function () { // Получить кусок данных из сессии... $value = session('key'); // Указать значение по умолчанию... $value = session('key', 'default'); // Сохранить кусок данных в сессию... session(['key' => 'value']); }); %% .(alert) Есть небольшое практическое отличие между использованием сессий через экземпляр HTTP-запроса и использованием глобального вспомогательного метода %%session()%%. Оба способа ((//docs/v5/testing тестируются)) методом %%assertSessionHas()%%, доступным во всех ваших тест-кейсах. **Получение всех данных сессии** Если вы хотите получить все данные из сессии, используйте метод %%all()%%: %% $data = $request->session()->all(); %% **Определение наличия элемента в сессии** Для проверки существования значения в сессии можно использовать метод %%has()%%. Этот метод вернёт %%(t)true%%, если значение существует и не равно %%null%%: %% if ($request->session()->has('users')) { // } %% Для проверки существования значения в сессии, даже если оно равно %%null%%, можно использовать метод %%exists()%%. Этот метод вернёт %%(t)true%%, если значение существует: %% if ($request->session()->exists('users')) { // } %% === Сохранение данных === Для сохранения данных в сессии обычно используются метод %%put()%% или вспомогательный метод %%session()%%: %% // Через экземпляр запроса... $request->session()->put('key', 'value'); // Через глобальный вспомогательный метод... session(['key' => 'value']); %% **Запись данных в массивы сессии** Метод %%push()%% служит для записи нового значения в элемент сессии, который является массивом. Например, если ключ %%(t)user.teams%% содержит массив с именами команд, вы можете записать новое значение в массив вот так: %% $request->session()->push('user.teams', 'developers'); %% **Чтение и удаление элемента** Метод %%pull()%% прочитает и удалит элемент из сессии за одно действие: %% $value = $request->session()->pull('key', 'default'); %% == Одноразовые данные == Иногда вам нужно сохранить переменную в сессии только для следующего запроса. Вы можете сделать это методом %%flash()%% (!!(tl_note)//flash// ^^англ.^^ - вспышка - //прим. пер.//!!). Сохранённые этим методом данные будут доступны только во время следующего HTTP-запроса, а затем будут удалены. В основном такие данные полезны для кратковременных сообщений о состоянии: %% $request->session()->flash('status', 'Задание выполнено успешно!'); %% %%(DOCNEW 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11) ~%% Session::flash('key', 'value'); ~%% %% Для сохранения одноразовых данных в течение большего числа запросов используйте метод %%reflash()%%, который оставит все эти данные для следующего запроса. А если вам надо хранить только определённые данные, то используйте метод %%keep()%%: %% $request->session()->reflash(); $request->session()->keep(['username', 'email']); %% %%(DOCNEW 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11) ~%% Session::reflash(); Session::keep(['username', 'email']); ~%% %% === Удаление данных === Метод %%forget()%% удалит куски данных из сессии. Для удаления из сессии всех данных используйте метод %%flush()%%: %% $request->session()->forget('key'); $request->session()->flush(); %% === Обновление ID сессии === Обновление ID сессии часто используется для защиты приложения от злоумышленников, применяющих атаку ((https://en.wikipedia.org/wiki/Session_fixation фиксации сессии)). Laravel автоматически обновляет ID сессии во время аутентификации, если вы используете встроенный %%(t)LoginController%%; но если вы хотите обновлять ID сессии вручную, используйте метод %%regenerate()%%. %% $request->session()->regenerate(); %% %%(DOCNEW 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11) С сессиями можно работать несколькими способами: с помощью метода %%session()%% HTTP-запросов, с помощью фасада %%(t)Session%%, или с помощью функции %%session()%%. При вызове функции %%session()%% без аргументов она возвратит весь объект сессии. Например: ~%% session()->regenerate(); ~%% **Сохранение переменной в сессии** ~%% Session::put('key', 'value'); session(['key' => 'value']); ~%% **Добавление элемента к переменной-массиву** ~%% Session::push('user.teams', 'developers'); ~%% **Чтение переменной сессии** ~%% $value = Session::get('key'); $value = session('key'); ~%% **Чтение переменной или возврат значения по умолчанию** ~%% $value = Session::get('key', 'default'); $value = Session::get('key', function() { return 'default'; }); ~%% **Прочитать переменную и забыть её** ~%% $value = Session::pull('key', 'default'); ~%% **Получение всех переменных сессии** ~%% $data = Session::all(); ~%% **Проверка существования переменой** ~%% if (Session::has('users')) { // } ~%% **Удаление переменной из сессии** ~%% Session::forget('key'); ~%% **Удаление всех переменных** ~%% Session::flush(); ~%% **Присвоение сессии нового идентификатора** ~%% Session::regenerate(); ~%% %% == Добавление своих драйверов сессий == **Реализация драйвера** Ваш драйвер сессий должен реализовывать %%(t)SessionHandlerInterface%%. Этот интерфейс содержит всего несколько простых методов, которые надо реализовать. Заглушка реализации MongoDB выглядит приблизительно так: %%