Что такое сессии в PHP

Технология сессии в PHP являются простым способом хранения информации для отдельно взятого пользователя сайта. Например: товары, добавленные в корзину магазина, настройки уведомлений и т.д. При первом запросе сайта к серверу, в браузере сохраняется в cookies уникальный идентификатор сессии пользователя. Затем идентификатор или связка идентификатора с IP адресом идентифицирует пользователя. Это может использоваться для сохранения состояния между запросами страниц. Идентификаторы сессий обычно отправляются браузеру через сессионный Cookie и используются для получения имеющихся данных сессии.
Сессии используют простую технологию: PHP будет либо получать данные существующей сессии, используя переданный идентификатор (обычно из сессионного cookie), или, если ничего не передавалось, будет создана новая сессия. PHP заполнит суперглобальную переменную $_SESSION сессионной информацией после того, как будет запущена сессия. Когда PHP завершает работу, он автоматически сериализует содержимое суперглобальной переменной $_SESSION и отправляет для сохранения, используя сессионный обработчик для записи сессии.
По умолчанию PHP использует внутренний обработчик files для сохранения сессий, который установлен в INI-переменной session.save_handler. Этот обработчик сохраняет данные на сервере в директории, указанной в конфигурационной директиве session.save_path.
Самый простой пример использования сессии, например, вывод количества обращений к странице для каждого пользователя:
<?php
session_start();
if (!isset($_SESSION['count'])) {
$_SESSION['count'] = 0;
} else {
$_SESSION['count']++;
}
echo $_SESSION['count'];
Пример работы скрипта можно посмотреть по адресу https://beget.com/session_test.php.
Каким способом возможна блокировка сессий
На сайте php в секции описания работы сессий есть примечание (http://php.net/manual/ru/session.examples.basic.php):
Скорее всего это станет проблемой для сайтов, которые активно используют AJAX и делают несколько одновременных запросов. Простейшим путем решить эту проблему будет вызов функции session_write_close() сразу же как только все требуемые изменения в сессии будут сделаны, предпочтительно ближе к началу работы скрипта. Также можно использовать другой механизм сессии, который поддерживает конкурентный доступ.
В последнее время проблема блокирования сессий становится всё более частой. Отчасти это связано с усложнением сайтов и необходимостью производить больше вычислений на строне сервера, а так же с большим распространением AJAX. К сожалению, не всегда логика приложения, особенно если она сложная, позволяет эффективно ограничить время блокировки конкурирующих за сессию процессов. Ситуация усугубляется еще тем, что 3-5 подобных клиентов способны быстро забить зависшими и простаивающими в ожидании процессами PHP-воркеры, в результате чего сайт начнёт выдавать 5XX ошибку.
Самый простой пример блокировки сессий:
<?php
session_start();
echo «Start»;
sleep(30);// только для одного скрипта
?>
Если открыть этот файл сначала в первой вкладке, а потом во второй — вторая вкладка будет ждать, пока не доработает первая. То есть фактически вторая вкладка будет дожидаться, пока первая не освободит файл сессии (что занимает в конкретном случае 30 секунд). Данная проблема хорошо описана в блоге компании 1С-Битрикс на Habrahabr.
Какие варианты решения данной проблемы существуют
Для хранения сессий можно использовать БД, такие как MySQL или PostgreSQL (что не совсем правильно, учитывая возможности большинства БД и возможную скорость работы в данной задаче), Memcached (не гарантирует хранение сессии, возможно ее удаление) и Redis, который мы считаем оптимальным хранилищем. По скорости он не уступает Memcached, но при этом может гарантировать сохранность данных.
И самое главное приемущество Redis - при хранении в нем сессий они не блокируются.
В рамках нашей панели управления (cp.beget.com) можно включить хранение сессий в Redis для всех сайтов на аккаунте. Для этого необходимо перейти в раздел "Сайты", и далее отметить галочку - "Хранить сессии всех сайтов в Redis".

