PHP :: Сессии
Что такое сессия?
Как было показано в предыдущем пункте, для того, чтобы отследить запросы от одного и того же пользователя, а также сохранить данные о нем между просмотрами отдельных страниц, можно использовать куки. Однако при этом данные сохраняются на стороне клиента, а там они могут быть подделаны, а также легко утеряны в результате переустановки браузера или чистки его кеша. Кроме того, пользователь может сам запретить прием куки, что сделает невозможным использование браузера для хранения данных о нем. Чтобы иметь возможность избежать таких сложностей, и был придуман механизм сессий, позволяющий хранить такие данные на стороне сервера, а не в браузере пользователя.
Сессия (от англ. session) – это механизм идентификации браузера пользователя и сохранения информации между последовательными доступами к веб-сайту, который позволяет сохранять данные о клиенте на стороне сервера.
Идентификация браузера (и, соответственно, пользователя) осуществляется посредством идентификатора сессии (session_id), который представляет собой обычную строковую переменную (по умолчанию ее имя - PHPSESSID) и присваивается каждому посетителю сайта, позволяя серверу отличить одного пользователя от другого (см. пример №1).
<?php //Запускаем сессию до любого другого вывода //как и в случае с отправкой куки session_start(); //Выводим имя сессии по умолчанию echo session_name().'<br>'; //Выводим идентификатор сессии echo session_id(); ?>
Пример №1. Запуск сессии
После того, как при помощи функции session_start() для данного пользователя будет запущена сессия с идентификатором session_id(), на сервере будет создан для нее временный файл, а также станет доступен специальный суперглобальный массив $_SESSION, который как раз и предназначен для хранения переменных текущей сессии пользователя на стороне сервера (в отличие от куки, которые хранятся на стороне пользователя).
Следует отметить, что если данные в куки теоретически могут храниться и несколько лет (в зависимости от параметров), то данные в суперглобальном массиве $_SESSION хранятся только до окончания сессии, т.е. до момента закрытия пользователем своего браузера. Точнее, по умолчанию в PHP сессия считается закрытой даже при открытом браузере, если посетитель ушел с сайта и не возвращался в течение 24 минут, т.к. в силу разных технических моментов определить точное время закрытия браузера пользователем невозможно.
После окончания сессии PHP автоматически удаляет ненужные сессионные файлы и, соответственно, все данные связанные с завершенной сессией. Поэтому, если информацию нужно сохранить на более длительное время, ее нужно сохранять отдельно, например, в базе данных или отдельном файле.
Что касается идентификатора сессии, то он хранится либо в cookie на стороне пользователя, либо передается через URL. В первую очередь PHP пытается установить пользователю куки, но также при старте сессии URL дополняется и id сессии на случай, если установка куки в браузере будет невозможна. При следующем запросе, если куки поддерживаются, PHP перестанет дополнять ссылки идентификаторами сессии. Если же прием куки в браузере пользователя будет отключен, то PHP будет постоянно добавлять id сессии к ссылкам, чтобы обеспечить сохранность текущей сессии.
Старт сессии в PHP
Для того, чтобы запустить или возобновить существующую сессию, в PHP присутствует функция session_start(), которую, как и вслучае с отправкой куки, следует вызывать в самом начале php-скрипта до вывода любой другой информации (см. пример №1). В случае удачного старта сессии функция возвращает TRUE, если же возникнет ошибка и сессия не стартует, функция вернет FALSE.
Перед стартом сессии, PHP проверяет наличие на компьютере пользователя id возможной недавно запускавшейся (текущей) сессии на другой или этой же странице. Если он находит такой идентификатор и он совпадает со значением, хранящимся на сервере, то считается, что предыдущая (т.е. текущая) сессия еще не закончена, и PHP возобновляет ее. Если же id не найден, то PHP запускает новую сессию и устанавливает для нее id.
id сессии в PHP
Для того, чтобы получить id текущей сессии или назначить ей новый идентификатор, нужно использовать функцию session_id(). При этом, если ни одна сессия не запущена и id явно не установлен, то session_id() вернет пустую строку.
Что касается установки для сессии своего идентификатора, то здесь важно помнить, что задаваемый id может состоять только из символов a-z, A-Z, цифр 0-9, запятой и знака минус (см. пример №2). Кроме того, сама функция session_id() должна быть вызвана до вызова функции session_start().
<?php //Устанавливаем свой идентификатор сессии session_id('My-id45'); //Запускаем сессию до любого другого вывода session_start(); //Выводим идентификатор сессии echo session_id(); ?>
Пример №2. Установка id сессии
Также хотелось бы отметить, что если установить один и тот же идентификатор сессии нескольким пользователям, то они смогут посещать страницу по одному и тому же сеансу, т.е. в окружении с одинаковыми параметрами (например, для них будет использоваться время одного и того же часового пояса).
Имя сессии в PHP
Кроме идентификатора сессия имеет еще и собственное имя, которое можно получить или установить при помощи функции session_name(). Если функция вызывается без параметра, то она возвращает имя текущей сессии (по умолчанию это PHPSESSID). Если аргумент в виде строки с именем, которое нужно установить сессии, присутствует, то функция перезаписывает текущее имя сессии на новое, но возвращает старое (см. пример №3).
<?php //Функцию нужно вызывать до старта сессии $old_name = session_name('html'); //А вот теперь стартуем и саму сессию session_start(); //Выводим новое имя запущенной сессии echo session_name().'<br>'; //Выводим id сессии html echo session_id().'<br>'; //Выводим старое имя сессии до перезаписи echo $old_name; ?>
Пример №3. Установка имени сессии
Важно помнить, что после установки имени сессии, функция session_name() должна вызываться каждый раз перед стартом самой сессии.
Также добавим, что использование собственного имени сессии особенно полезно, если на одном сервере расположены несколько сайтов одного веб-мастера. В этом случае PHP сервера сможет правильно различать сеансы одного и того же пользователя, но к разным сайтам. В результате не будет возникать досадных ошибок с использованием переменных ранее запущенной, но еще не закрытой, на другом сайте сессии.
Суперглобальный массив $_SESSION
Как уже был сказано выше, после старта сессии необходимые данные могут быть занесены в суперглобальный массив $_SESSION и позднее доступны на любой странице сайта, на которой будет запущена сессия (см. пример №4). При этом следует помнить, что если после запуска сессии мы создадим свой массив и поместим туда переменные, то они доступны другим страницам не будут.
//------- Первая страница -------- <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Суперглобальный массив $_SESSION</title> </head> <body> На данной странице мы стартуем сессию и заносим<br> данные в суперглобальный массив $_SESSION, которые<br> далее будут доступны на любой странице сайта, где<br> будет запущена текущая сессия. Убедимся в этом,<br> совершив переход на 2-ю страницу <a href="example_8_15_2.php">здесь</a> и<br> попробовав вывести данные массива на страницу. <?php //Стартуем сессию session_start(); //Заносим данные в массив $_SESSION['my_name']="Иван Иванович"; ?> </body> </html> //------- Вторая страница -------- <?php //Стартуем сессию session_start(); ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Вывод данных массива $_SESSION</title> </head> <body> Выводим данные массива, помещенные в массив на первой странице: <?php echo $_SESSION['my_name']?>.<br> Попробуйте закомментировать старт сессии! </body> </html>
Пример №4. Использование суперглобального массива $_SESSION
Чтобы данные после окончания сессии не терялись, их можно поместить в базу данных, после чего использовать по необходимости, например, для сбора общей статистики посещений страниц сайта или же восстановления настроек пользователя при его последующем возвращении на сайт.
Удаление переменных сессии
Если нужно удалить все переменные связанные с текущей сессией, нужно использовать функцию session_unset(). В результате суперглобальный массив $_SESSION будет очищен (см. пример №5). Если же нужно удалить только некоторые данные, то можно использовать функцию unset() (например, unset($_SESSION['var_name']) удалит элемент массива с указанным ключем).
Важно помнить, что применять конструкцию unset($_SESSION) не стоит, иначе будут удалены не только переменные сессии, но и сам суперглобальный массив.
<?php //Стартуем сессию session_start(); //Выведем id запущенной сессии echo 'id сессии : '.session_id().'<br>'; //Заносим какие-нибудь данные в массив $_SESSION['my_name']="Иван Иванович"; //Проверяем наличие данных print_r($_SESSION); //Очищаем массив $_SESSION session_unset(); //Пробуем вывести (получим ошибку) echo $_SESSION['my_name']; //Но массив при этом не удаляется (он пустой) print_r($_SESSION); //Сама сессия остается открытой, проверяем это echo '<br>Сессия работает : '.session_id().'<br>'; //Заносим заново данные в массив $_SESSION['my_name']="Иван Иванович"; //Проверяем наличие данных print_r($_SESSION); ?>
Пример №5. Удаление переменных сессии
Закрытие сессии в PHP
Чтобы закрыть саму сессию и удалить данные связанные с ней (например, идентификатор сессии), необходимо использовать функцию session_destroy(). После вызова данной функции текущая сессия закрывается, но данные суперглобального массива и установленных куки не удаляются (см. пример №6). Поэтому, для очистки массива $_SESSION нужно использовать session_unset(), а для удаления куки - функцию setcookie().
<?php //Стартуем сессию session_start(); //Заносим в массив id запущенной сессии $_SESSION['my_name']=session_id(); //Проверяем наличие данных print_r($_SESSION); //Удаляем все переменные сессии еще до закрытия, //чтобы PHP мог понять, какие данные удалять session_unset(); //Закрываем сессию session_destroy(); //Удаляем куки, если нужно, чтобы сессия после //вызова session_start() не запустилась опять //setcookie('PHPSESSID', '', time()-500, '/'); ?>
Пример №6. Завершение сессии
Запустите пример №6 в своем браузере (откройте фрейм в новой вкладке или окне). Затем обновите страницу с примером несколько раз, после чего сделайте тоже самое, но прежде снимите комментирование для строки удаления куки. В результате можно будет увидеть, что если куки не удалять, то при каждом обновлении страницы прежняя сессия будет восстанавливаться (в массив будет заноситься один и тот же session_id). Если же куки с данными открытой сессии удалять, то при обновлении страницы будет запускаться новая сессия (в массив каждый раз будет заноситься другое значение session_id).
Подробнее об остальных функциях для работы с сессиями можно узнать в официальном справочнике в разделе «Справочник функций» -> «Расширения для работы с сессиями» -> «Функции для работы с сессиями».