Вы когда-нибудь задумывались, как сайт запоминает, что вы уже вошли в аккаунт? Или почему корзина в интернет-магазине не очищается, когда вы переходите на другую страницу? Всё это — магия сессий и куки. Если вы пишете на PHP, то рано или поздно столкнётесь с ними. Давайте разберёмся, как они работают и как их готовить, чтобы не сломать голову.

Digital-студия WNDER

Что такое куки и сессии: аналогия из жизни

Представьте, что вы пришли в бар. Бармен вас не знает, но хочет запомнить, что вы заказали. Он может выдать вам бумажку с номером столика (куки) или повесить бейджик на шею (сессия). Разница в том, где хранится информация. Куки — это файлы на компьютере пользователя. Сессии — это данные на сервере, а пользователю достаётся только идентификатор (тот самый бейджик).

Куки — маленькие текстовые файлы, которые браузер сохраняет и отправляет обратно на сервер с каждым запросом. Они живут долго (если задать время жизни) и могут быть прочитаны на клиенте. Сессии — это механизм PHP, который хранит данные на сервере и связывает их с конкретным пользователем через уникальный ID, обычно передаваемый в куки.

Вот основные отличия в таблице:

Характеристика Куки Сессии
Где хранятся На клиенте (браузер) На сервере
Безопасность Низкая (можно подделать) Высокая (данные не у клиента)
Объём До 4 КБ Ограничен настройками сервера
Время жизни Задаётся при установке До закрытия браузера (по умолчанию)

Как работать с куки в PHP

Установить куки в PHP проще простого — функция setcookie(). Но у неё есть нюанс: она должна вызываться до вывода любого HTML. Иначе получите ошибку «Headers already sent».

<?php
// Устанавливаем куки с именем 'user' и значением 'John' на 1 час
setcookie('user', 'John', time() + 3600, '/');

// Читаем куки
if (isset($_COOKIE['user'])) {
    echo 'Привет, ' . htmlspecialchars($_COOKIE['user']) . '!';
} else {
    echo 'Привет, гость!';
}

// Удаляем куки (устанавливаем время жизни в прошлом)
setcookie('user', '', time() - 3600, '/');
?>

Параметры setcookie():

Параметр Описание
name Имя куки
value Значение
expire Время жизни (Unix timestamp)
path Путь на сервере, для которого доступна куки
domain Домен, которому доступна куки
secure Только по HTTPS
httponly Доступ только через HTTP (не из JavaScript)
Правило: Всегда устанавливайте флаг httponly для куки, которые не должны быть доступны из JavaScript. Это защитит от XSS-атак. А для критичных данных используйте secure, чтобы куки передавались только по HTTPS.

Сессии в PHP: старт, запись, чтение

Сессии в PHP запускаются функцией session_start(). Она должна быть вызвана в начале каждого скрипта, где вы хотите работать с сессией. После этого можно писать в $_SESSION и читать оттуда.

<?php
// Стартуем сессию
session_start();

// Записываем данные
$_SESSION['user_id'] = 123;
$_SESSION['role'] = 'admin';

// Читаем
if (isset($_SESSION['user_id'])) {
    echo 'Вы вошли как пользователь #' . $_SESSION['user_id'];
}

// Удаляем одну переменную
unset($_SESSION['role']);

// Полностью уничтожаем сессию
session_destroy();
?>

По умолчанию сессии хранятся в файлах на сервере (в папке, указанной в session.save_path). Но можно хранить их в базе данных или Redis — так надёжнее в высоконагруженных проектах.

Важный момент: session_start() тоже должна вызываться до вывода HTML. Если выводите что-то раньше, используйте буферизацию вывода (ob_start()).

Безопасность: как не попасться

Сессии и куки — лакомый кусочек для хакеров. Вот несколько угроз и способы защиты:

  • Кража сессии (Session Hijacking): злоумышленник получает ID сессии и притворяется пользователем. Защита: используйте HTTPS, устанавливайте флаг secure для куки сессии, регенерируйте ID при входе (session_regenerate_id()).
  • Фиксация сессии (Session Fixation): атакующий навязывает жертве свой ID сессии. Защита: та же регенерация ID после аутентификации.
  • XSS (Cross-Site Scripting): внедрение JavaScript для кражи куки. Защита: флаг httponly для куки сессии, экранирование вывода.
  • CSRF (Cross-Site Request Forgery): выполнение действий от имени пользователя. Защита: использование токенов в формах.
Лайфхак: Установите в php.ini параметры session.cookie_httponly = 1 и session.cookie_secure = 1 (если сайт на HTTPS). Это автоматически применится ко всем сессионным куки.

Ещё один совет: не храните в куки пароли, номера кредиток и другую чувствительную информацию. Для этого есть сессии.

Практические примеры: авторизация и корзина

Давайте соберём простую авторизацию с использованием сессии.

<?php
session_start();

// Допустим, у нас есть пользователь из базы
$user = ['id' => 1, 'login' => 'admin', 'password_hash' => password_hash('secret', PASSWORD_DEFAULT)];

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $login = $_POST['login'] ?? '';
    $password = $_POST['password'] ?? '';

    if ($login === $user['login'] && password_verify($password, $user['password_hash'])) {
        // Аутентификация успешна
        session_regenerate_id(true); // защита от фиксации
        $_SESSION['user_id'] = $user['id'];
        $_SESSION['login'] = $user['login'];
        header('Location: /dashboard.php');
        exit;
    } else {
        $error = 'Неверный логин или пароль';
    }
}
?>

А теперь пример корзины на куки (для неавторизованных пользователей).

<?php
// Добавляем товар в корзину
$productId = 42;
$cart = isset($_COOKIE['cart']) ? json_decode($_COOKIE['cart'], true) : [];
$cart[] = $productId;
setcookie('cart', json_encode($cart), time() + 86400 * 30, '/');

// Выводим содержимое корзины
if (!empty($cart)) {
    echo 'В корзине товары: ' . implode(', ', $cart);
} else {
    echo 'Корзина пуста';
}
?>

Но помните: куки ограничены 4 КБ, так что для больших корзин лучше использовать сессию или базу данных.

Что в итоге

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

Главные правила: всегда стартуйте сессию до вывода HTML, используйте httponly и secure для куки, регенерируйте ID сессии при входе. И не храните в куки то, что может навредить пользователю.

Надеюсь, теперь работа с сессиями и куки в PHP не будет для вас тёмным лесом. Пробуйте, экспериментируйте, но не забывайте о безопасности.

Студия WNDER