Php сессии
Содержание:
Введение
HTTP-приложения не имеют состояний. Сессии — способ сохранения информации о пользователе между отдельными запросами. Laravel поставляется со множеством различных механизмов сессий, доступных через единый выразительный API. Из коробки поддерживаются такие популярные системы, как Memcached, Redis и СУБД.
Настройка
Настройки сессии содержатся в файле config/session.php. Обязательно просмотрите параметры, доступные вам в этом файле. По умолчанию Laravel использует драйвер сессий file, который подходит для большинства приложений. Для увеличения производительности сессий в продакшне вы можете использовать драйверы memcached или redis.
Настройки драйвера определяют, где будут храниться данные сессии для каждого запроса. Laravel поставляется с целым набором замечательных драйверов:
- file — данные хранятся в storage/framework/sessions.
- cookie — данные хранятся в виде зашифрованных .
- database — хранение данных в реляционной БД.
- memcached / redis — для хранения используются эти быстрые кэширующие хранилища.
- array — сессии хранятся в виде PHP-массивов и не будут сохраняться между запросами.
Внимание: драйвер array обычно используется во время тестирования, так как он на самом деле не сохраняет данные для последующих запросов.
Требования для драйверов
Database
При использовании драйвера сессий database вам необходимо создать таблицу для хранения данных сессии. Ниже — пример такого объявления с помощью конструктора таблиц:
Для создания этой миграции вы можете использовать Artisan-команду :
Redis
Чтобы использовать сессии Redis в Laravel, необходимо установить пакет predis/predis (~1.0) с помощью Composer. Вы можете настроить подключения Redis в файле настроек database. А в файле session в параметре connection можно указать конкретное подключение Redis для сессии.
+
5.2 5.1 5.0
добавлено в
5.2
(08.12.2016)
5.1
(19.06.2016)
5.0
(08.02.2016)
Другие рекомендации для сессий
Laravel использует внутренний ключ сессий flash, поэтому нельзя добавлять элемент с таким именем в сессию.
Если вы хотите шифровать все хранимые данные сессий, установите значение параметра encrypt равное true.
+
5.0
добавлено в
5.0
(08.02.2016)
Внимание: При использовании драйвера сессий cookie, никогда не удаляйте посредника EncryptCookie из вашего HTTP-ядра. Если вы это сделаете, ваше приложение станет уязвимым для удалённого внедрения кода.
Ещё раз про функции session_name() и session_id()
Функции и на практике используются редко, но я о них пишу, так как в статье нужно раскрыть сам механизм работы сессий в PHP.
При помощи этих функций можно задавать собственные имена и идентификаторы сессий, но делать это не рекомендуется. Если вы захотели задать их, то пропишите эти функции с аргументами перед функцией , как в примере ниже:
смотреть пример
При использовании данного примера всем пользователям будет назначен один и тот же идентификатор сессии.
Тут подробней остановимся, если вы запустите пример из секции про функцию (вот ссылка) в разных браузерах (например в Chrome и в Internet Explorer), то в каждом браузере будет свой, уникальный идентификатор сессии. Браузеры хранят файлы cookies каждый в своей папке, поэтому функция даст каждому браузеру создать свой, уникальный идентификатор и, соответственно, для каждого браузера будет создано уникальное хранилище на сервере. Поэтому пример со счётчиком (этот) в каждом браузере будет работать независимо друг от друга.
Если задать одинаковый идентификатор сессии для всех пользователей, то они будут работать с одним хранилищем на сервере. Вот пример счётчика, который будет считать посещения с разных браузеров:
смотреть пример
Если вы запустите этот пример, то не факт что вы увидите там единицу. Другие посетители могли уже изменить значения в хранилище сессий на сервере. Когда в этом случае сервер удаляет хранилище — я не знаю, поэтому при превышении счётчиком значения 100 буду завершать сессию.
Одноразовые данные
Иногда вам нужно сохранить переменную в сессии только для следующего запроса. Вы можете сделать это методом (flash англ. — вспышка — прим. пер.). Сохранённые этим методом данные будут доступны только во время следующего HTTP-запроса, а затем будут удалены. В основном такие данные полезны для кратковременных сообщений о состоянии:
+
5.0
добавлено в
5.0
(08.02.2016)
Для сохранения одноразовых данных в течение большего числа запросов используйте метод , который оставит все эти данные для следующего запроса. А если вам надо хранить только определённые данные, то используйте метод :
+
5.0
добавлено в
5.0
(08.02.2016)
Обновление ID сессии
Обновление ID сессии часто используется для защиты приложения от злоумышленников, применяющих атаку фиксации сессии.
Laravel автоматически обновляет ID сессии во время аутентификации, если вы используете встроенный LoginController; но если вы хотите обновлять ID сессии вручную, используйте метод .
+
5.0
добавлено в
5.0
(08.02.2016)
С сессиями можно работать несколькими способами: с помощью метода HTTP-запросов, с помощью фасада Session, или с помощью функции . При вызове функции без аргументов она возвратит весь объект сессии. Например:
Сохранение переменной в сессии
Добавление элемента к переменной-массиву
Чтение переменной сессии
Чтение переменной или возврат значения по умолчанию
Прочитать переменную и забыть её
Получение всех переменных сессии
Проверка существования переменой
Удаление переменной из сессии
Удаление всех переменных
Присвоение сессии нового идентификатора
Открываем PHP-сессию
Сегодня я хочу рассказать, как использовать сессии PHP в WordPress. В стандартном PHP-приложении сессия начинается после вызова функции session_start, запущенной в начале PHP-скрипта. Вам нужно открыть файл header.php используемой темы и добавить туда следующий код:
<?php session_start(); ?> <!DOCTYPE html> <head> ....
Но этот метод сложно назвать самым эффективным. WordPress предлагает API Actions, к которому можно привязывать собственные функции. В приведенном далее примере используется как раз этот метод. Добавьте следующий код в самое начало файла functions.php.
- Мы воспользуемся событием init, с помощью которого можно запустить PHP-сессию. При первой инициализации WordPress мы добавляем действие, которое вызывает функцию:
add_action('init', 'start_session', 1);
Далее создаем функцию start_session
Обратите внимание, что функция сначала проверяет, активна ли сессия, и только потом запускает новую сессию при помощи функции session_id:
function start_session() { if(!session_id()) { session_start(); } }
Закрываем PHP-сессию
Функция session_destroy позволяет очистить сессию PHP. Но когда именно вызывать эту функцию? Многое зависит от самого приложения. WordPress также предлагает несколько способов реализовать это при помощи API Actions.
- В WordPress может потребоваться очистить сессию при выходе пользователя из системы, либо при авторизации нового пользователя на сайте. Для вызова функции end_session(), которую мы создадим позже, будут использоваться хуки wp_logout и wp_login:
add_action(‘wp_logout’, ‘end_session’); add_action(‘wp_login’, ‘end_session’);
- Далее создаем функцию end_session:
function end_session() { session_destroy (); }
Принудительное закрытие сессии
Можно использовать собственный хук, чтобы с помощью PHP закрыть сессию в любом фрагменте шаблона. Мы воспользуемся do_action для вызова функции end_session, которую мы создали выше.
- В файл functions.php нужно добавить следующий код:
add_action('end_session_action', 'end_session');
Если вы все сделали правильно, то самый верх вашего файла functions.php будет выглядеть следующим образом:
add_action('init', 'start_session', 1); function start_session() { if(!session_id()) { session_start(); } add_action(‘wp_logout’, ‘end_session’); add_action(‘wp_login’, ‘end_session’); add_action(‘end_session_action’, ‘end_session’); function end_session() { session_destroy (); }
Теперь нужно добавить глобальную переменную $_SESSION, которой можно воспользоваться в любой момент при работе с приложением. Переменная является массивом, и ниже приведен пример добавления данных в массив сессии:
$foo = ‘Foo Data’; $_SESSION = $foo;
Что нужно учесть:
Если вы занимаетесь разработкой масштабируемого сайта, то возможно вам и не придется использовать эти сессии. HTTP – это протокол без запоминания состояний, сессии PHP основываются на состояниях. Сессии хранятся на сервере и обрабатываются им же. Маршрутизация каждой сессии до нужного сервера требует более сложной конфигурации, и создает проблемы для пользователей, чьи сессии хранятся на этом сервере.
По возможности, информацию о сессиях лучше хранить в браузере. Это позволит сэкономить ресурсы сервера, а также избавиться от ненужного функционала.
Подробно о проверке запуска/существования сессии с примерами
- -> сессия не запущена
- -> сессия запущена
-
Создадим живой пример проверки существования сессии — будем использовать выше приведенный пример.
Добавим кнопку, по нажатию на которую…
Если сессия существует — удалим сессию, + перезагрузимся, чтобы скрипт сработал сначала и вывел, сто сессия не существует.
Иначе(т.е. сессия не существует) — создай сессию по нажатию на кнопку + перезагрузимся, после этого скрипт снова должен сработать и выдать результат, что сессия создана!
Ячейка сессии $_SESSION не существует
Логика скрипта и необходимые условия:
В одной части проверяем существует ли ячейка сессии, в ней выполняем все соответствующие действия.
if($_SESSION)
{
$echo2 ='<greenblock>Ячейка сессии $_SESSION существует и равна: <span style=»color:black;»>’.$_SESSION.'</span></greenblock>’;
$button = ‘Удали сессию, которую создал!’;
if($_POST)
{
unset($_SESSION);
echo'<meta http-equiv=»Refresh» content=»0; URL=»>’;
}
}
Иначе выполняем противоположные действия:
else
{
$echo2 ='<redblock>Ячейка сессии $_SESSION не существует</redblock>’;
$button = ‘Создай сессию, которая не существует!’;
if($_POST)
{
$_SESSION = ‘значение_ячейки_сессии’;
echo'<meta http-equiv=»Refresh» content=»0; URL=»>’;
}
}
Добавляем form
+ post
+ button
+ submit
Скачать скрипт проверки существования сессии php!
Для данного параграфа у нас есть:
Скачать пример с не запущенной сессией в
Для данного параграфа — мы создали специальную страницу(см.выше пример), где изначально сессия не запущена!
И теперь разберемся, как данный код работает!
Нам потребовался простой каркас html страницы
На странице разместили вот такое условие():
<? if ($_SESSION) { echo ‘Сессия уже запущена ранее…’; } else { echo ‘Сессия не существует…’; } ?></red>
Скачать пример с не запущенной сессией в
<!DOCTYPE html><head><html lang=»ru»><meta charset=»UTF-8″><title>Пример скрипта Проверить запущена ли сессия php</title>
<link rel=»stylesheet» type=»text/css» href=»https://dwweb.ru/__a-data/__all_for_scripts/__examples/__examples.css»>
</head>
<body>
<blockCenter>
<h2>Вывод проверки запущена сессия php или нет!? </h2>
Да… совсем забыл сказать, что сессия не запущена
<l>Результат</l>
<div class=»kod»>
<red><? if ($_SESSION) { echo ‘Сессия уже запущена ранее…’; } else { echo ‘Сессия не существует…’; } ?></red>
</div>
</blockCenter>
</body>
</html>
Как работает удаление сессии по клику.
удаления сессии по клику!
Как и ранее запускаем сессии :
session_start();
Условие первой линии, если сессия существует, то внутри расположим условие второй линии:
if ($_SESSION)
Иначе(else) первой линии:
$rezult = ‘Нельзя удалить то, что не существует! Нужно создать сессию’;
Условие второй линии(внутри первого если(if))
1). Если $_POST существует:
2). Удаляем сессию -> $_SESSION
3). Если сессия удалена, выводим результат -> $rezult
4). Перезагружаем принудительно -> meta
if ($_POST)
{
$_SESSION=»;
if (!$_SESSION) { $rezult = ‘Сессия $_SESSION удалена’; }
echo ‘<meta http-equiv=»refresh» content=»2; url=»></head>’;
}
Иначе(else) второй линии, сработает в том случае, если сессия все еще существует, но кнопка удалить не нажата!
Выводим кнопку удалить сессию!
$rezult = ‘Сессия $_SESSION существует — её можно удалить’;
$form = ‘<form method=»post»>
<input type=»submit» name=»submit» value=»Удалить сессию PRIMER»>
</form> ‘;
Соберем весь код вместе:
Логика работы сессии
Session (или сессия) это некое временное хранилище данных. Сразу предупреждаю, сохранять стоит небольшой объём данных. Например, логин и пароль заходящего пользователя или его порядковый номер в базе данных.
Пример работы1. Пользователь вводит логин и пароль и заходит на сайт2. Данные с логином и паролем сохраняются в сессии одной из страниц сайта:
Файл index.php
session_start(); // каждый файл, в котором Вы хотите использовать данные сессий должен в начале кода содержать команду «запуска сессии»
$login = ‘admin’; $password = ‘pass’; $_SESSION = $login; // сохраняем переменную содержащую логин $_SESSION = $password; // сохраняем переменную содержащую пароль
3. При переходе на другую страницу сайта эти данные также будут доступны:
Файл example.php (или любая другая страница)
session_start(); // снова «запускаем сессиию»
echo «Ваш логин «.$_SESSION; // выведет «Ваш логин admin», хотя на этой странице мы не записывали данных! Видите, все просто!
4. Если хотите очистить данные сессии, то достаточно:
Файл example.php
session_start(); // снова «запускаем сессиию»
unset($_SESSION); // так разрегистрировали переменную или «уничтожили» echo «Ваш логин «.$_SESSION; // выведет «Ваш логин » . Так как мы её уничтожили в прошлой строке, то и данных нет
session_destroy(); // разрушаем сессию. Всех данных, включая $_SESSION уже нет. При их запросе будет выводить ошибка В целом подобная передача похожа на метод POST, но только Вы уже не должны писать много лишнего кода, а все данные, передаваемые от страницы к странице, хранятся во временных файлах на сервере. Повторюсь, сессии должны содержать небольшие объёмы данных, поэтому они подходят под хранение логина/пароля, корзины покупателя и других небольших объёмов.
Клиентские веб-сеансы
Сеансы на стороне клиента используют файлы cookie и криптографические методы для поддержания состояния без сохранения большого количества данных на сервере. При представлении динамической веб-страницы сервер отправляет данные о текущем состоянии клиенту (веб-браузеру) в виде файла cookie. Клиент сохраняет cookie в памяти или на диске. При каждом последующем запросе клиент отправляет cookie обратно на сервер, и сервер использует данные, чтобы «запомнить» состояние приложения для этого конкретного клиента и сгенерировать соответствующий ответ.
Этот механизм может хорошо работать в некоторых контекстах; однако данные, хранящиеся на клиенте, уязвимы для несанкционированного доступа со стороны пользователя или программного обеспечения, имеющего доступ к клиентскому компьютеру. Чтобы использовать сеансы на стороне клиента, где требуются конфиденциальность и целостность, необходимо гарантировать следующее:
- Конфиденциальность: ничто, кроме сервера, не должно интерпретировать данные сеанса.
- Целостность данных: ничто, кроме сервера, не должно манипулировать данными сеанса (случайно или злонамеренно).
- Аутентичность: ничто, кроме сервера, не должно инициировать действительные сеансы.
Для этого серверу необходимо зашифровать данные сеанса перед их отправкой клиенту, и изменение такой информации любой другой стороной должно быть предотвращено с помощью криптографических средств.
Передача состояния туда и обратно с каждым запросом практична только в том случае, если размер файла cookie небольшой. По сути, сеансы на стороне клиента обменивают дисковое пространство сервера на дополнительную пропускную способность, которая требуется для каждого веб-запроса. Более того, веб-браузеры ограничивают количество и размер файлов cookie, которые могут храниться на веб-сайте. Чтобы повысить эффективность и предоставить больше данных сеанса, сервер может сжимать данные перед созданием файла cookie, распаковывая его позже, когда файл cookie возвращается клиентом.
Использование состояния сеанса
Взаимодействовать с состоянием сеанса можно с помощью класса System.Web.SessionState.HttpSessionState, который на веб-странице ASP.NET доступен в виде встроенного объекта Session. Синтаксис для добавления элементов в эту коллекцию и их извлечения выглядит практически так же, как и синтаксис, который используется для добавления элементов в состояние представления страницы.
Например, вот как сохранить объект DataSet в памяти сеанса:
После этого его можно извлечь с помощью соответствующей операции преобразования:
Контекст состояния сеанса охватывает все приложение и является глобальным для текущего пользователя. Данные состояния сеанса могут быть утеряны в следующих случаях:
-
Если пользователь закрывает и заново запускает браузер.
-
Если пользователь получает доступ к той же странице через другое окно браузера, хотя сеанс будет по-прежнему существовать, если доступ к веб-странице получается из исходного окна браузера. Разные браузеры ведут себя в такой ситуации по-разному.
-
Если сеанс завершается из-за отсутствия активности со стороны пользователя. По умолчанию сеанс автоматически завершается после 20 минут простоя.
-
Если программист завершает сеанс вызовом метода Session.Abandon().
В первых двух случаях данные состояния сеанса фактически остаются в памяти сервера, потому что веб-сервер не разбирается в том, закрыл клиент окно браузера или открыл новое. Они будут продолжать находиться там, оставаясь недоступным, до тех пор, пока не истечет срок их хранения.
Вдобавок данные состояния сеанса также будут утеряны и в случае повторного создания домена приложения. Этот процесс происходит автоматически при обновлении веб-приложения либо изменении конфигурационных параметров. Домен приложения также может создаваться заново через определенные промежутки времени для поддержания приложения в нормальном работоспособном состоянии. Если такое поведение приводит к возникновению проблем, данные состояния сеанса можно хранить вне процесса. В таком случае они не потеряются даже в результате завершения домена приложения.
В таблице ниже перечислены основные методы и свойства класса HttpSessionState:
Метод или свойство | Описание |
---|---|
Count | Количество элементов в коллекции текущего сеанса |
IsCookieless | Указывает, как отслеживается этот сеанс: с помощью cookie-набора или с использованием измененных URL-адресов |
IsNewSession | Указывает, был ли данный сеанс только что создан для текущего запроса. Если в состоянии сеанса на текущий момент не содержится никакой информации, ASP.NET не будет беспокоиться ни об отслеживании сеанса, ни о создании cookie-набора сеанса. Вместо этого сеанс будет воссоздаваться заново при каждом запросе |
Mode | Предоставляет перечислимое значение, которое объясняет, как ASP.NET хранит информацию о состоянии сеанса. Этот режим хранения определяется на основе указанных в файле web.config конфигурационных настроек |
SessionID | Предоставляет строку с уникальным идентификатором сеанса для текущего клиента |
StaticObjects | Предоставляет коллекцию элементов сеанса, предназначенных только для чтения, которые были объявлены в global.asax с помощью дескрипторов <object runat=»server»>. В основном эта технология не используется и является пережитком ASP-программирования; она поддерживается для обратной совместимости |
Timeout | Текущее количество минут, которое должно пройти, прежде чем текущий сеанс будет завершен при условии отсутствия запросов от клиента. Это значение может изменяться программно, что дает возможность при необходимости продлевать срок жизни коллекции сеанса для более важных операций |
Abandon() | Немедленно завершает текущий сеанс и освобождает все занятые им ресурсы памяти. Такая технология полезна на автономных страницах, поскольку позволяет освобождать ресурсы памяти сервера настолько быстро, насколько возможно |
Clear() | Удаляет все элементы сеанса, но не изменяет идентификатор текущего сеанса |
Создание сессии
Общий принцип работы сессий рассматривался в прошлом уроке. Из него стало ясно, что PHP связывает данные, хранимые на сервере, и конкретного пользователя с помощью записи уникального идентификатора в cookie. Все сессионные данные доступны через суперглобальный массив $_SESSION. Однако прежде чем осуществлять запись или чтение данных из него, нужно явным образом создать сессию.
В PHP есть специальная функция session_start(). Она осуществит проверку присланных заголовков HTTP-запроса на наличие cookie с идентификатором сессии. Если идентификатор отсутствует, будет создана новая сессия, иначе функция откроет обработчики чтения-записи и синхронизирует текущие сеансовые данные с массивом $_SESSION. Функция возвращает булево значение true в случае успешного завершения, а false, если произошли ошибки.
Как вы уже знаете, настройка сессий происходит с помощью конфигурационного файла php.ini. Для этого используется ряд директив, с полным списком которых вы ознакомитесь на странице официальной документации.
Начиная с версии PHP 7.0 эти настройки могут быть переопределены динамически за счет передачи в функцию session_start() массива, ключами которого являются имена директив без слова session (см. пример).
//если пользователь не будет 10 секунд посылать запросы //на сервер, его сессия будет автоматически удалена session_start(); if (isset($_SESSION)) { $difference = time() — $_SESSION; echo «От старта сессии прошло {$difference}сек»; } else { $_SESSION = ; echo ‘Создана новая сессия’; }
Заметка Параметр функции session_start() является необязательным. На практике необходимость переопределения каких-либо настроек не встречается.
Вход в систему
Имя пользователя и пароль передаются сценарию PHP с именем login.php. Этот сценарий использует глобальную переменную $_POST для получения строк, введенных в поля имени пользователя и пароля. После этого устанавливается соединение с базой данных ‘session’ и из нее извлекаются соответствующие имени пользователя идентификатор пользователя и пароль. Если имя пользователя обнаруживается, пароль, хранимый в базе данных, сравнивается с паролем, введенным пользователем. Если пароли не совпадают, попытка входа в систему отклоняется. В противном случае осуществляется вход. Ниже представлен код сценария login.php:
<?php
/*login.php*/
function check_login($username, $password)
{
if (!($username && $password))
return false;
$con=mysql_connect(‘127.0.0.1′,’user’,’pass’) or die(mysql_error());
mysql_select_db(‘session’,$con) or die(mysql_error());
$result = mysql_query(«SELECT id, decode(pass,’session’) as pass FROM user WHERE name='» . addslashes($username) . «‘;»,$conn) or die(mysql_error());
if(mysql_num_rows($result) != 1) {
printf(«<center><h1>User %s not found</h1><br /><a href=»login.html»>Go to login page</a></center>», $username);
return false;
}
if(mysql_result($result, 0, ‘pass’) != $password) {
printf(«<center><h1>Login attempt rejected for %s!</h1><br /><a href=»login.html»>Go to login page</a></center>», $username);
return false;
}
session_start();
$_SESSION = $username;
$_SESSION = mysql_result($result,0,’id’);
mysql_close($conn);
return true;
}
if(check_login($_POST, $_POST))
printf(«<center><h1>Welcome %s!</h1><br /><br />n»,$_SESSION);
print(«<a href=»status.php»>Check status!</a><br /><a href=»protectedimage.php»>View Protected Image</a><br /><a href=»logout.php»>Logout</a></center>n»);
?>
В случае, если имя пользователя и пароль корректны, вызывается функция session_start(), которая в свою очередь отправляет куки с идентификатором сессии пользователя клиенту. Данные кук показаны на Рисунке 4. После этого становится возможным доступ к данным с помощью вызовов $_SESSION или $_SESSION для получения или сохранения данных сессии. В данном случае в массиве $_SESSION сохраняются имя и идентификатор пользователя.
Рисунок 4: Куки сессии (PHPSESSID) показаны в списке кук браузера Firefox
Созданный с помощью функции session_start() идентификатор сессии хранится в куках на машине клиента. Вы можете исследовать куки, воспользовавшись пунктами меню Firefox «Правка->Настройки», выбрав вкладку «Приватность» и нажав на ссылку «удалить отдельные куки». После этого будет выведен список кук, отсортированный по имени сервера. В данном случае в качестве имени сервера используется адрес 127.0.0.1 и в качестве имени переменной кук используется строка ‘PHPSESSID’ — вы можете заметить ее в поле ‘Содержимое’ (‘Content’) в области вывода информации. Страница приветствия, показанная после входа в систему, изображена на Рисунке 5.
Рисунок 5: Страница приветствия, выводящаяся после успешного входа