В данной заметке коротко о том, как использовать сеансы (сессии) в PHP, как они работают и как они связаны с файлами cookie (куки).

Официальная документация здесь

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

Сессия — это механизм для сохранения информации на разных веб-страницах для идентификации пользователей при навигации по сайту или приложению. Сессия PHP представляет собой способ хранения информации в переменных сессии, которые могут быть использованы для аутентификации на нескольких веб-страницах. В отличие от куков, информация сессии не хранится на компьютере пользователя. Вместо этого сессия создает файл на сервере во временном каталоге.

Рекомендуется настроить путь для хранения сессий на сервере. Сделать это можно несколькими способами. Необходимо заранее создать указанные директории!

В файле php.ini:

session.save_path = "/path"

// Моя настройка в Windows 10 
session.save_path = "S:\Server\session"

В файле .htaccess:

php_value session.save_path "/path"

// Моя настройка в Windows 10 
php_value session.save_path "S:\Server\session"

Выше варианты для глобальной конфигурации хранения сессий. Можно настраивать хранение сессий для каждого проекта отдельно. Для этого в проекте необходимо вызвать php функцию session_save_path() c указанием необходимого пути. Перед session_start() укажем путь для хранения сессий проекта:

session_save_path("S:\Server\session");
session_start();

Второй вариант:

ini_set('session.save_path', "S:\Server\session");
session_start();

Создание сессии (сеанса) в PHP

Для того, чтобы начать сеанс (запустить сессию), необходимо вызвать функцию session_start(). Данную функцию нужно запускать вначале каждой страницы, на которой мы хотим в дальнейшем прочитать данные из сессии.

При каждом вызове session_start() PHP сам отправляет куку в браузер пользователя.

// Синтаксис
session_start ([ array $options = array() ] ) : bool

// Пример
session_start ();

С помощью аргументов (ассоциативный масс $options) можно переопределить текущие директивы конфигурации сессий, которые указаны в php.ini. Список всех директив: здесь

Запись и чтение сессий

После того, как на сервере создался файл вида sess_..., в данную сессию можно записать информацию, а так же считать её от туда.

// Запись в сессионную переменную
$_SESSION['name'] = 'John';

// Чтение из сессионной переменной
echo $_SESSION['name'];

Завершение (очистка) сессии

Так как сессии часто используются для авторизации пользователей, то нужно иметь механизм "выхода" из системы. Для того, чтобы завершить сессию нам нужно:

  • Очистить массив $_SESSION
  • Удалить временное хранилище (файл сессии) на сервере
  • Удалить сессионную куку (cookie).
// Очистить массив $_SESSION полностью
session_unset();

// Удалить сессионную переменную
unset($_SESSION['age']);

// Удалить временное хранилище (файл сессии) на сервере
session_destroy();

// Принудительное удаление сессионной cookie
setcookie(session_name(), session_id(), time()-3600);
  • session_id() - уникальный идентификатор сессии
  • session_name() - значение идентификатора сессии

Итоги

// Создание и(или) доступ к сессии
session_start();

// Запись в сессионную переменную
$_SESSION['name'] = 'John';

// Чтение из сессионной переменной
echo $_SESSION['name'];

// Удалить сессионную переменную
unset($_SESSION['age']);

// Очистить массив $_SESSION полностью
session_unset();

// Удалить временное хранилище (файл сессии) на сервере
session_destroy();

// Принудительное удаление сессионной cookie
setcookie(session_name(), session_id(), time()-3600);


// Простой пример использования сессий
session_save_path('С:\temp');
session_start();
if (!isset($_SESSION['counter'])) $_SESSION['counter'] = 0;
echo "Вы обновили эту страницу ".$_SESSION['counter']++." раз. ";
echo "<br><a href=".$_SERVER['PHP_SELF'].">обновить";

Пример использования сессии

В данном примере я покажу как можно использовать сессии (сеансы) в PHP на практике. Для начала на сервере создадим файл index.php со следующим содержимым:

<?
// Создаётся пустой файл вида sess_819gk3tcdvilccra1t9kjdvsv9
// На машину пользователя прилетает сессионная кука с ID сессии. В данном случае 819gk3tcdvilccra1t9kjdvsv9
session_start();

// Инициализация строки с сообщениями об ошибках
$message = '';

// Если запрос отправлен методом POST
if ($_SERVER["REQUEST_METHOD"] == "POST"):
  $name = strip_tags($_POST["name"]);
  $age = (int)$_POST["age"];

  // Если поле `name` не заполнено
  if(empty($name)):
      $message = 'Поле `Ваше имя` обязательно к заполнению!';
  // Иначе, если поле `age` не заполнено
  elseif(empty($age)):
      $message = 'Поле `Ваш возраст` обязательно к заполнению!';
  // Если поля заполнены, записываем в сессию
  else:
      $_SESSION["name"] = $name;
      $_SESSION["age"] = $age;
  endif;

// Иначе берём данные из сессии
else:
    $name = $_SESSION["name"] ?? null;
    $age = $_SESSION["age"] ?? null;
endif;
?>
<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>Сессии</title>
</head>
<body>
<h1>Создание сессии</h1>
<p><a href="destroy.php">Закрыть сессию</a></p>
<p><?= $message ?></p>
<form action="<?= $_SERVER["PHP_SELF"] ?>" method="post">
    Ваше имя: <br>
    <input type="text" name="name" value="<?= $name ?>"><br><br>
    Ваш возраст: <br>
    <input type="text" name="age" value="<?= $age !== 0 ? $age : '' ?>"><br><br>
    <input type="submit" value="Отправить">
</form>
<?
if ($name and $age) {
    echo "<h3>Привет, $name!</h3>";
    echo "<h3>Тебе $age лет</h3>";
}
?>
</body>
</html>

Здесь я постарался максимально понятно описать всё происходящее. Под пользователя при заходе на эту страницу уже создаётся сессия, она пустая, это пока просто файл. Если пользователь заполнил все необходимые поля формы и нажал кнопку `Отправить`, то созданный файл (файл сессии) заполниться данными. Далее скрипт проверяет, если есть в сессии данные именно этого пользователя (здесь он уже сравнивает с кукой, которая пришла до этого на машину пользователя), то выводим эти данные. В противном случае, добавляем в сессию данные пользователя.

Создадим файл destroy.php. При переходе на данную страницу будем удалять сессию полностью. Если необходимо удалять и сессионную куку, воспользуйтесь функцией:

setcookie(session_name(), session_id(), time()-3600);
// Файл destroy.php
<? session_start() ?>
<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <title>Закрыть сессию</title>
</head>
<body>
  <h1>Сессия закрыта</h1>
  <a href="index.php">Создать сессию</a>
</body>
</html>
<? session_destroy() ?>