Сессии
Автор: | Артемьев Сергей Игоревич |
ICQ: | 438856621 |
email: | _spin_@bk.ru |
Одной из особенностей протокола HTTP является "отсутствие памяти". Это означает, что сервер "забывает" пользователя сразу же после окончания HTTP-сессии (загрузки страницы). Даже если просто обновить ранее загруженную страницу - сервер будет считать, что к нему обратился новый пользователь.
Для статического сайта это вполне достаточно, т.к. содержимое страниц не меняется и всем пользователям показывается одно и то же.А вот для динамических сайтов дело обстоит намного хуже - здесь сервер должен каким-то образом отличать пользователей друг от друга и выдавать каждому из них нужные данные.
PHP предлагает решение на основе сессий. Сессия - это набор параметров и значений, однозначно определяющих пользователя. Каждая сессия обладает собственным уникальным идентификатором, поэтому пользователю достаточно сообщить серверу идентификатор своей сессии и сервер "вспомнит" все подробности и историю запросов пользователя.
Идентификатор сессии автомаически сохраняется в браузере пользователя в виде cookie, а если браузер cookie не поддерживает - идентификатор добавляется автоматически к адресу страницы и всем ссылкам на ней. Это значит, что при обновлении страницы браузер сам отправит на сервер идентификатор сессии, независимо от действий пользователя.
В зависимости от настроек PHP сессии могут создаваться либо вручную, либо автоматически при первом обращении пользователя. У большинство провайдеров автоматическое создание сессий не включено из соображений производительности и безопасности.
Для создания новой сессии необходимо вызвать функцию session_start() без параметров, после этого станет доступен глобальный массив $_SESSION и в cookies браузера пользователя появится элемент PHPSESSID.
<?php session_start(); $_SESSION['sampleName'] = 'Иван Иваныч'; echo $_SESSION['sampleName']; ?>
Сессия инициируется один раз, а все повторные вызовы session_start() приводят только к появлению предупреждения "Сессия уже открыта, повторное открытие не допускается.". Для проверки, была ли уже вызвана функция session_start() существует специальная функция session_id(). Эта функция всегда возвращает строку с идентификатором сессии, но если сессия ещё не создана - строка будет пустой.
<?php // открываем сессию только если она ещё // не была открыта ранее if(session_id() == '') session_start(); ?>
Этот приём очень удобен, когда ваш скрипт подключает другие скрипты, в которых так же может быть вызвана session_start().
Для того, чтобы ваши данные сохранялись на сервере при переходах между страницами, достаточно поместить их в глобальный массив $_SESSION. Например:
<?php // открываем сессию session_start(); // проверяем на наличие имени в URL-запросе if(isset($_GET['name'])) { // получаем имя $name = $_GET['name']; // и сохраняем его в сессии $_SESSION['name'] = $name; echo 'Имя извлечено из GET-запроса' . "<br />\n"; } // иначе - проверяем наличие имени в сессии elseif(isset($_SESSION['name'])) { // извлекаем имя из сессии $name = $_SESSION['name']; echo 'Имя извлечено из данных сессии' . "<br />\n"; } // иначе - выводим сообщение об ошибке. else { $name = 'не обнаружено'; echo 'Имя не обнаружено' . "<br />\n"; } // выводим имя echo 'Моё имя: ' . $name; ?>
Сохраните этот код в файле myname.php в корневом каталоге локального сервера и перейдите по адресу http://localhost/myname.php. Скрипт выведет сообщение, что имя не обнаружено.
Теперь измените адрес страницы, дописав к нему "?name=Ivan" и перейдите по новому адресу. Скрипт сообщит, что обнаружил имя в GET-запросе, и что ваше имя -Ivan. А теперь снова перейдите по первому адресу (без параметров). Скрипт сообщает, что имя извлечено из данных сессии, и что ваше имя по прежднему Ivan,
Иногда возникают ситуаци, когда надо заново сгенерировать идентификатор сессии. Для этого служит функция session_regenerate_id(). Вызывать её нужно после открытия сессии:
<?php if(session_id() == '') session_start(); else session_regenerate_id(); ?>
Показаный приём иногда используется при защите сайтов от атак, заключающихся в подмене злоумышленником своего идентификатора сессии на идентификатор пользователя с более высокими привилегиями. Подобрать чужой идентификатор практически невозможно, а вот узнать (прослушивая сеть сниффером или пользуясь троянами) - возможно.
Элементы сессии могут быть не только простых типов, но и массивами:
<?php ... $_SESSION['myWorkWeek'] = array(); ... $_SESSION['myWorkWeek']['monday'] = 'Понедельник'; $_SESSION['myWorkWeek']['tuesday'] = 'Вторник'; ... $_SESSION['myWorkWeek']['friday'] = 'Пятница'; echo 'Мои рабочие дни: ' . implode(', ', $_SESSION['myWorkWeek']); // выведет: // Мои рабочие дни: Понедельник, Вторник, ... ?>
Сессию можно закрыть или уничтожить. Закрытие сессии происходит при вызове функции session_write_close(). При этом все изменения, сделанные в сессии, сохраняются в дисковом кеше. Если же необходимо закрыть сессию и удалить все её данные - надо вызвать session_destroy() или session_unset(). Отличие между ними в том, что session_unset() может использоваться в старом коде, где недоступен глобальный массив $_SESSION.
<?php ... // освобождаем все переменные сессии $_SESSION = array(); // стираем cookie идентификатора сессии if (isset($_COOKIE[session_name()])) { setcookie(session_name(), '', time()-42000, '/'); } // уничтожаем сессию session_destroy(); ?>
Как видите, работать с сессиями достаточно просто. Только не надо забывать, что объём данных, сохраняемых в сессии, в конце концов конечен и не надо сохранять лишнего.