Работа с сессиями в PHP
Сессия, механизм php, созданный для возможности передачи данных предназначенных конкретному пользователю при повторных запросах (веб-сервер не поддерживает постоянного соединения с клиентом, и каждый запрос обрабатывается, как новый, без какой-либо связи с предыдущими).
Принцип работы сессий: сервер выдает браузеру уникальный идентификатор, и просит передавать его с каждым запросом. Передача происходит стандартными способами, либо через куки, либо через переменные POST/GET.
Идентификатор сессии — это обычная переменная, по умолчанию ее имя — PHPSESSID. Можно изменить директивой session.name в php.ini.
На сервере за передачу информации о сессиях отвечают две настройки в php.ini:
- session.use_cookies — если равно 1, то PHP передает идентификатор в куках, если 0 — то нет.
- session.use_trans_sid — если равно 1, то PHP передает его, добавляя к URL и формам, если 0 — то нет.
Соответственно, если включена только первая настройка и браузер отдает куки, то идентификатор передается через них, если не отдает, то сессия обнуляется при каждом запросе.
Если включена только вторая, то PHP дописывает к каждой относительной ссылке и к каждой форме передачу идентификатора сессии, примерно так:
Если включены обе, то браузеру выставляется кука, а ссылки и формы дополняются только если кука найдена не была.
Вся информация о сессии храниться в глобальном массиве $_SESSION.
Запись данных в сессию работает так:
// запускаем новую, либо возобновляем существующую сессию session_start(); // передаем в массив сессий переменную с названием test и данными Hello world $_SESSION['test']='Hello world!'; // если в качестве имени переменной хотим использовать значение переменной - // пишем без кавычек или используем двойные $var = name; $_SESSION["$var"]='Hello world!';
// обычное условие проверки if(!$_SESSION[$var]){ echo "session variable is empty" } // можно получить id текущей сессии или ее имя session_id(); session_name();
Удаление переменных из сессии:
unset($_SESSION[$var]); // Если register_globals = on, надо добавить строку session_unregister($var); //Если надо сбросить все переменные сессии session_unset();
Для закрытия сессии используется функция:
Данные из глобального массива $_SESSION php хранит либо в файлах, путь к которым указывается в session.save_path в php.ini, либо в БД.
Для управления HTTP-заголовками отвечающими за кэш, используется функция session_cache_limiter(). Установка nocache, например, отменяет кэширование на стороне клиента.
Во время начала запроса режим кеширования сбрасывается до значения по умолчанию, хранящегося в session.cache_limiter. Таким образом, вам необходимо вызывать session_cache_limiter() для каждого запроса (перед тем, как вызвана функция session_start()).
Значение | Посылаемый заголовок |
---|---|
public | Expires: (когда-нибудь в будущем, в зависимости от session.cache_expire) Cache-Control: public, max-age=(когда-нибудь в будущем, в зависимости от session.cache_expire) Last-Modified: (временная метка последнего сохранения сессии) |
private_no_expire | Cache-Control: private, max-age=(session.cache_expire в будущем), pre-check=(session.cache_expire в будущем) Last-Modified: (временная метка последнего сохранения сессии) |
private | Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: private, max-age=(session.cache_expire в будущем), pre-check=(session.cache_expire в будущем) Last-Modified: (временная метка последнего сохранения сессии) |
nocache | Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache |
Возможные проблемы
- Вспомогательными вещами, вроде кодирования данных и удаления старых сессий, php занимается сам, и если возникает проблема с удалением информации о них, проверьте в php.ini строку session.gc_probability. Для того чтобы php мог самостоятельно удалять файлы сессий, должно быть установлено 1.
- Warning: open(/tmp\sess_SID, O_RDWR) failed: No such file or directory (2) in full_script_path on line number
или
Warning: Failed to write session data (files). Please verify that the current setting of session.save_path is correct (/tmp))
в этом случае надо в php.ini, в параметре session.save_path, указать правильный каталог, который существует и доступен для записи (не забудьте перезагрузить апач). - Warning: Cannot send session cookie — headers already sent.
Warning: Cannot send session cache limiter — headers already sent.
Warning: Cannot add header information — headers already sent.
эти ошибки возникают в том случае, если браузер ранее уже получил заголовки для страницы. Функции header(), session_start(), setcookie() и вся логика, которая их вызывает, должны обрабатываться до любого вывода в браузер. - Если давать переменным скрипта имена, совпадающие с индексами массива $_SESSION, возможны проблемы. При register_globals=on значения будут перезаписывать друг друга. При register_globals=off, в случае, если в скрипте есть переменная сессии не имеющая значения, и глобальная переменная с тем же именем, появится ошибка «Your script possibly relies on a session side-effect which existed until PHP 4.2.3.». Для предотвращения этой ошибки, надо инициализировать переменные перед использованием или проверять на существование, и стараться не давать глобальным переменным имена, совпадающие с индексами массива $_SESSION.
- Если вы используете перенаправление через header или навигацию с помощью JavaScript, PHP не пропишет необходимый идентификатор, т.к. он работает только со статичными ссылками. В этом случае надо проставлять идентификатор самостоятельно:
header("Location: /script.php?".session_name().'='.session_id());
Более детальный обзор можно найти на сайте phpfaq.ru
Простая авторизация на PHP.
В этой статье мы напишем очень простую авторизация на web странице. Мы не буде использовать базы данных и т.д. Все будет очень лаконично и просто.
Допустим у нас есть страница index.php на которую могут заходить только авторизованные пользователи. Для ограничения доступа мы будем проверять есть ли сессии для этого пользователя или если проще, авторизован пользователь. Создадим файл и запишем в него такой код :
session_start();
if($_SESSION['admin'] != "admin") header("Location: login.php");
exit;
>
?>
Вы авторизованы .
session_start(); # Открыли сессию , обязательно условие при работе с сессиями.
header(«Location: login.php»); # производим редирект пользователя на страницу login.php
exit; # После функции header() обязательно завершаем выполнение скрипта при помощи функции exit(). Данный код очень просто, если у нас в массиве $_SESSION нету переменой admin равной значению ‘admin’ перенаправить на страницу авторизации.
Ну и за одно создадим страницу авторизации login.php :
Простой html код создания формы с двумя полями и кнопкой отправки, метод передачи данных post. Если мы все правильно сделали , то при попытки зайти на index.php нас должно выкидывать на форму авторизации.
Следующим этапом мы добавим обработчик данных из формы. Который будет принимать и сравнивать данные из формы. В этом примере у нас будет только один пользователь и хранить логин\пароль мы будем прям в этом же файле. Пароль будет в зашифрованном виде c помощью функции md5(). А что бы узнать узнать хеш пароля попробуйте выполнить код echo md5(‘mypass’); 😉 Делать это мы будем по условию — только в том случае, если нажата кнопка формы.
У кнопки есть имя («submit»), а данные мы передаем методом post. Соответственно, мы можем просто проверить, существует ли элемент submit в массиве $_POST. Если есть — кнопка была нажата, и мы будем выполнять действия по проверке присланных данных, иначе — ничего делать не будем.
В файл формы (login.php) в самое начало добавим код :
else echo 'Логин или пароль неверны!
'; > ?>
Когда создается сессия, PHP генерирует уникальный идентификатор, который представляет собой случайную строку.Все переменные сессии хранятся на сервере во временном файле.
Сервер отправляет на компьютер пользователя куки, называемые PHPSESSID, для хранения строки уникального идентификатора сессии.
Когда пользователь закрывает браузер, сессия PHP закрывается автоматически. Иначе сервер завершит сессию по истечении заданного периода времени.
В заключение мы сделаем ссылку для удаления всех данных сессии (закрыть сессию). Мы передаем один параметр — do и при этом присвоим ему значение «logout». А в блок PHP добавим проверку значения элемента do из массива $_GET. Если оно будет равно строке «logout» — мы просто удалим сессию с помощью session_destroy() . Откроем файл index.php и добавим код :
Вставим этот код сразу после session_start(); для проверки полученных данных.
if($_GET['do'] == 'logout') unset($_SESSION['admin']);
session_destroy();
>
Ошибка в тексте? Выделите её и нажмите «Ctrl + Enter»