Вы когда-нибудь задумывались, как сайт запоминает, что вы уже вошли в аккаунт? Или почему корзина в интернет-магазине не очищается, когда вы переходите на другую страницу? Всё это — магия сессий и куки. Если вы пишете на PHP, то рано или поздно столкнётесь с ними. Давайте разберёмся, как они работают и как их готовить, чтобы не сломать голову.
Что такое куки и сессии: аналогия из жизни
Представьте, что вы пришли в бар. Бармен вас не знает, но хочет запомнить, что вы заказали. Он может выдать вам бумажку с номером столика (куки) или повесить бейджик на шею (сессия). Разница в том, где хранится информация. Куки — это файлы на компьютере пользователя. Сессии — это данные на сервере, а пользователю достаётся только идентификатор (тот самый бейджик).
Куки — маленькие текстовые файлы, которые браузер сохраняет и отправляет обратно на сервер с каждым запросом. Они живут долго (если задать время жизни) и могут быть прочитаны на клиенте. Сессии — это механизм 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 не будет для вас тёмным лесом. Пробуйте, экспериментируйте, но не забывайте о безопасности.



