📚
#52 06.10.2025 PHP Basics

Что представляет собой суперглобальный массив $_COOKIE в PHP, как он формируется и какие критические меры безопасности необходимо соблюдать при работе с ним?

$_COOKIE — суперглобальный массив с HTTP cookies от браузера. Все значения — строки, легко подделываются клиентом. Никогда не доверяйте важным данным из кук. Всегда проверяйте (??), валидируйте и экранируйте. Используйте для настроек, не для авторизации.

Подробнее
⚠️
Внимание! Этот текст был сгенерирован AI-ассистентом. Информация может содержать неточности и требует проверки.

Полный ответ:

1. Основное назначение

$_COOKIE — это суперглобальный ассоциативный массив, который содержит данные HTTP cookies, переданные браузером на сервер.

Содержимое:

// Куки установленные в браузере: username=John; theme=dark
print_r($_COOKIE);
// Array(
//     'username' => 'John',
//     'theme' => 'dark'
// )

2. Установка cookies vs чтение

Важное различие:

  • Чтение: через $_COOKIE (данные от браузера)
  • Запись: через setcookie() или setrawcookie()
// Установка куки
setcookie('username', 'John', time() + 3600, '/', '.example.com', true, true);

// Чтение куки
$username = $_COOKIE['username'] ?? 'Guest';

3. Особенности данных

Все значения — строки:

// Куки: user_id=123
echo gettype($_COOKIE['user_id']); // string (не integer!)

Ограничения:

  • Размер: до 4KB на одну куку
  • Количество: ограничено браузером (обычно 50+ на домен)
  • Символы: нельзя использовать: ; , = пробелы в имени

4. Безопасность — КРИТИЧЕСКИ ВАЖНО!

Куки полностью контролируются клиентом и могут быть легко подделаны.

Уязвимость к подделке:

// ОПАСНО: доверие данным куки
$isAdmin = $_COOKIE['is_admin'] === 'true';
if ($isAdmin) {
    grantAdminAccess(); // Любой пользователь может стать админом!
}

// БЕЗОПАСНО: проверка на сервере
$userRole = getUserRoleFromDatabase($userId);
if ($userRole === 'admin') {
    grantAdminAccess();
}

XSS-атаки:

// ОПАСНО: прямой вывод
echo "Welcome, " . $_COOKIE['username'];

// БЕЗОПАСНО: экранирование
echo "Welcome, " . htmlspecialchars($_COOKIE['username'] ?? '', ENT_QUOTES, 'UTF-8');

5. Проверка существования кук

Всегда проверяйте наличие кук перед использованием:

// ПЛОХО: может вызвать Notice
$theme = $_COOKIE['theme'];

// ХОРОШО: проверка существования
if (isset($_COOKIE['theme'])) {
    $theme = $_COOKIE['theme'];
} else {
    $theme = 'light';
}

// ЛУЧШЕ: с использованием null coalescing (PHP 7+)
$theme = $_COOKIE['theme'] ?? 'light';

// С приведением типа
$userId = (int) ($_COOKIE['user_id'] ?? 0);

6. Валидация и фильтрация

Базовая валидация:

$theme = $_COOKIE['theme'] ?? '';

// Разрешенные значения
$allowedThemes = ['light', 'dark', 'auto'];
if (!in_array($theme, $allowedThemes)) {
    $theme = 'light';
}

Проверка целостности данных:

// Для важных данных используйте подпись
function getVerifiedCookie($name, $secret) {
    if (!isset($_COOKIE[$name], $_COOKIE[$name . '_sig'])) {
        return null;
    }
    
    $value = $_COOKIE[$name];
    $signature = hash_hmac('sha256', $value, $secret);
    
    if (hash_equals($signature, $_COOKIE[$name . '_sig'])) {
        return $value;
    }
    
    return null; // Подпись не совпала - кука подделана
}

7. Практическое применение

Настройки пользователя:

// Язык интерфейса
$language = $_COOKIE['language'] ?? 'en';

// Тема оформления
$theme = in_array($_COOKIE['theme'] ?? '', ['light', 'dark']) 
    ? $_COOKIE['theme'] 
    : 'light';

Трекер аналитики:

// Идентификатор сессии/пользователя
$sessionId = $_COOKIE['session_id'] ?? '';

// UTM-метки
$utmSource = $_COOKIE['utm_source'] ?? 'direct';

8. Особенности работы

Время жизни:

  • Куки доступны в $_COOKIE только после перезагрузки страницы
  • Установленные куки setcookie() появятся в $_COOKIE при следующем запросе

Пример:

// Первый запрос
setcookie('test', 'value'); // Устанавливаем куку

// $_COOKIE['test'] еще не существует!
echo $_COOKIE['test'] ?? 'not set'; // 'not set'

// Второй запрос (после перезагрузки)
echo $_COOKIE['test'] ?? 'not set'; // 'value'

9. Best Practices

  1. Никогда не храните чувствительные данные в куках (пароли, токены API)
  2. Используйте флаги httponly и secure при установке кук
  3. Валидируйте все данные из $_COOKIE
  4. Используйте подписи для важных кук
  5. Устанавливайте разумное время жизни
setcookie('preferences', $data, [
    'expires' => time() + 86400 * 30,
    'path' => '/',
    'domain' => '.example.com',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Strict'
]);

10. Отличие от сессий

$_COOKIE vs $_SESSION:

  • Куки: хранятся в браузере, ограниченный размер, могут быть подделаны
  • Сессии: хранятся на сервере, безопаснее, больший размер

Итог:

$_COOKIE — суперглобальный массив с данными HTTP cookies от браузера. Ключевые особенности:

  • Данные от клиента → крайне ненадежны
  • Все значения — строки → требуется приведение типов
  • Легко подделываются → никогда не доверяйте важным данным
  • Требуют строгой валидации и проверки подлинности
  • Идеальны для настроек UI, предпочтений, но не для авторизации

Используйте куки только для нефункциональных данных, а для авторизации — сессии или JWT-токены.