Чтение куки в языке PHP: полное руководство
Получение куки в PHP
Основной и наиболее эффективный способ получения куки в PHP - использование суперглобального массива $_COOKIE. Этот массив автоматически заполняется всеми куки, переданными в HTTP-запросе, и предоставляет прямой доступ к значениям по имени.
// Пример получения куки с именем 'user'
$user = $_COOKIE['user'] ?? null;
if ($user) {
echo 'Привет, ' . htmlspecialchars($user);
} else {
echo 'Куки не найдена.';
}Php получить куки (получение куки в php)
Обратите внимание: перед использованием куки следует проверять её существование с помощью isset() или оператора ??, чтобы избежать ошибок уровня E_WARNING.
Возможные проблемы и ошибки:
- Куки, установленные через
setcookie()в текущем запросе, не будут доступны в$_COOKIEдо следующего HTTP-запроса. Это связано с тем, что$_COOKIEотражает только куки, полученные от клиента. - Имена куки могут содержать только буквы, цифры и некоторые символы (точка, подчеркивание, дефис). Если имя содержит пробелы или специальные символы, доступ через
$_COOKIE['name']может не сработать; в таких случаях требуется работа с сырым заголовком (см. варианты ниже). - Безопасность: не доверяйте данным из куки - всегда экранируйте вывод с помощью
htmlspecialchars()для предотвращения XSS-атак.
Цель использования:
Массив $_COOKIE является стандартным инструментом для чтения куки в любых PHP-приложениях - от простых скриптов до фреймворков. Он прост, быстр и не требует дополнительных настроек.
Как получить значение куки с фильтрацией входных данных?
Для безопасного получения куки с возможностью фильтрации типов используйте функцию filter_input(). Она принимает тип входных данных (INPUT_COOKIE), имя переменной и необязательные флаги фильтрации.
// Получение куки 'email' с фильтром FILTER_VALIDATE_EMAIL
$email = filter_input(INPUT_COOKIE, 'email', FILTER_VALIDATE_EMAIL);
if ($email === false) {
echo 'Некорректный email в куки';
} elseif ($email === null) {
echo 'Куки не найдена';
} else {
echo 'Email: ' . htmlspecialchars($email);
}Php получить html (получение html-кода в php)
Особенности и ошибки:
filter_input()возвращаетnull, если переменная не существует, иfalseпри ошибке фильтрации. Важно различать эти случаи.- Функция использует исходные данные из запроса, минуя изменения, внесённые в
$_COOKIE(например, если вы изменили массив в коде ранее). - Не все фильтры применимы к строкам - выбирайте подходящий (например,
FILTER_SANITIZE_STRINGдля общего использования).
Цель: использование в проектах, где требуется строгая типизация и фильтрация входящих данных, например, в связке с очисткой пользовательского ввода.
Как получить сырую строку куки из HTTP-заголовка?
Иногда нужно обработать все куки целиком или разобрать нестандартный формат. Для этого можно обратиться к суперглобальному массиву $_SERVER['HTTP_COOKIE'], который содержит оригинальную строку заголовка Cookie:.
$rawCookie = $_SERVER['HTTP_COOKIE'] ?? '';
// Пример разбора строки вручную
echo $rawCookie;
// Вывод: user=john; session=abc123Php получить заголовок (получение заголовка в php)
Проблемы:
- В некоторых конфигурациях сервера (например, при использовании CGI) массив
$_SERVER['HTTP_COOKIE']может отсутствовать. Тогда используетсяgetallheaders()илиapache_request_headers(). - Ручной разбор требует внимательности: куки могут содержать точки с запятой, пробелы и символы, экранированные по правилам HTTP.
Цель: отладка, работа с нестандартными куки (например, с именем, содержащим запрещённые символы) или когда стандартный $_COOKIE не подходит.
Как работать с куки, имеющими массивы (например, multipart-куки)?
В PHP куки могут быть структурированы как массивы с помощью квадратных скобок в имени (например, cart[item1]). $_COOKIE автоматически преобразует такие имена в многомерный массив.
// Установка массивной куки (через setcookie не работает, надо использовать setrawcookie)
setrawcookie('cart[item1]', 'book');
setrawcookie('cart[item2]', 'pen');
// В следующем запросе:
$cart = $_COOKIE['cart'] ?? [];
print_r($cart);
/* Вывод:
Array
(
[item1] => book
[item2] => pen
)
*/Php получить json (получение json в php)
Важно:
- Функция
setcookie()не поддерживает массивы - она запишет имя как строкуcart[item1], но не разберёт его. Используйтеsetrawcookie()или формируйте заголовок вручную. - При чтении через
$_COOKIEPHP автоматически разбирает квадратные скобки, что удобно для передачи списков.
Цель: хранение простых списков или конфигураций в одной куки, что упрощает управление данными на клиенте.
Как получить куки с помощью сторонней библиотеки (например, Symfony HttpFoundation)?
Во фреймворках куки обычно оборачиваются в объекты. Например, в Symfony вы можете получить доступ к куки через Request объект.
// В контроллере Symfony
use Symfony\Component\HttpFoundation\Request;
public function index(Request $request)
{
$cookieValue = $request->cookies->get('theme', 'default');
// ...
}Php получить адрес (получение адреса в php)
Особенности:
- Библиотека предоставляет дополнительные методы для проверки существования (
has()), удаления и установки куки. - Не используйте сторонние библиотеки без необходимости - для простых проектов достаточно
$_COOKIE.
Цель: единообразие в крупных приложениях, удобство тестирования и расширяемость.
Как получить куки в командной строке (CLI) при эмуляции HTTP-запроса?
В CLI-сценариях суперглобальные массивы не заполняются. Чтобы симулировать куки, нужно установить их вручную через $_SERVER['HTTP_COOKIE'] или использовать библиотеки.
// В скрипте CLI
$_SERVER['HTTP_COOKIE'] = 'session=abc; user=john';
// Теперь $_COOKIE не заполнится автоматически, нужно разобрать строку
$cookies = [];
foreach (explode(';', $_SERVER['HTTP_COOKIE']) as $pair) {
$parts = explode('=', trim($pair), 2);
if (count($parts) === 2) {
$cookies[trim($parts[0])] = trim($parts[1]);
}
}
print_r($cookies);
Проблемы:
- В CLI нет реального HTTP-запроса, поэтому
$_COOKIEвсегда пуст. Необходимо самим заполнять$_COOKIEпосле разбора строки, если требуется. - Разбор строки вручную может быть неточным при сложных значениях (например, содержащих точки с запятой).
Цель: тестирование скриптов, работающих с куки, в консольном режиме или при отладке.
Расширенные примеры получения куки в PHP
Пример 1: Получение всех куки и их вывод с безопасным экранированием
// Перебор всех доступных куки
if (!empty($_COOKIE)) {
foreach ($_COOKIE as $name => $value) {
echo htmlspecialchars("$name: $value", ENT_QUOTES, 'UTF-8') . "\n";
}
} else {
echo "Куки не найдены.\n";
}
user: john theme: dark
Пример 2: Получение куки со значением, содержащим специальные символы (например, json)
// Предположим, в куки 'preferences' хранится JSON-строка
$rawPref = $_COOKIE['preferences'] ?? '{}';
$pref = json_decode($rawPref, true);
if (json_last_error() === JSON_ERROR_NONE) {
echo 'Цвет фона: ' . htmlspecialchars($pref['bg_color'] ?? 'белый');
} else {
echo 'Некорректный JSON в куки';
}
Цвет фона: синий
Пример 3: Использование filter_input с флагом FILTER_SANITIZE_STRING для очистки
$name = filter_input(INPUT_COOKIE, 'username', FILTER_SANITIZE_STRING);
if ($name !== null) {
echo 'Имя пользователя после санитизации: ' . $name;
} else {
echo 'Куки отсутствует';
}
Этот пример удаляет HTML-теги и потенциально опасные символы из значения куки.
Пример 4: Получение куки с помощью getallheaders() (альтернатива $_SERVER)
$headers = getallheaders();
$cookieString = isset($headers['Cookie']) ? $headers['Cookie'] : '';
echo "Строка Cookie из заголовков: $cookieString\n";
// Разбор вручную (упрощённый)
$cookies = [];
foreach (explode(';', $cookieString) as $pair) {
if (strpos($pair, '=') !== false) {
list($key, $val) = explode('=', $pair, 2);
$cookies[trim($key)] = trim($val);
}
}
print_r($cookies);
Строка Cookie из заголовков: session=abc123; user=john
Array
(
[session] => abc123
[user] => john
)
Пример 5: Работа с куки через PECL-расширение http (если установлено)
// Расширение http предоставляет класс HttpMessage и методы работы с куки
$request = new HttpMessage($_SERVER);
$cookies = $request->getHeaders()->get('Cookie');
// В более новых версиях: $request->getCookieParams()
echo $cookies;
Этот вариант редко используется, но может быть полезен для продвинутой работы с HTTP.
Пример 6: Имитация куки в unit-тестах (с помощью фиктивных значений)
// В тестовом классе PHPUnit
$_COOKIE = [
'session_id' => 'test_session_123',
'user_role' => 'admin'
];
// Теперь тестируемый код видит эти куки
$role = $_COOKIE['user_role'] ?? 'guest';
$this->assertEquals('admin', $role);
Примечание:
После теста необходимо очистить или переопределить $_COOKIE, чтобы не повлиять на другие тесты.
Пример 7: Получение куки с учётом поддоменов и путей (прямая манипуляция)
// Стандартный $_COOKIE не содержит информации о domain и path,
// но можно получить эти данные из сырого заголовка при помощи регулярных выражений
// (заголовок Set-Cookie не передаётся обратно, только Cookie)
// Для проверки use case: если куки установлена на .example.com, браузер отправляет её всем поддоменам.
// В $_COOKIE она будет доступна без указания domain.
Этот пример не требует кода, но иллюстрирует ограничение: в $_COOKIE нет метаданных о куки.