Как программисту PHP извлечь User-Agent
При разработке веб-приложений часто требуется определить, с какого браузера или устройства пришёл запрос. Эта информация передаётся в заголовке HTTP User-Agent. В PHP есть несколько способов получить это значение. Рассмотрим каждый из них с примерами и типичными проблемами.
Основной способ получения User-Agent
Как получить User-Agent из HTTP-запроса?
Самый надёжный и распространённый метод - использование суперглобального массива $_SERVER['HTTP_USER_AGENT']. Этот элемент создаётся веб-сервером из соответствующего заголовка.
<?php
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
echo $userAgent;
?>
App path php (работа с путями файлов в php)
Если заголовок отсутствует (например, в консольном скрипте), $_SERVER не содержит такого ключа. Поэтому рекомендуется проверять его существование через оператор ?? (null coalescing) или isset(). В противном случае скрипт выдаст предупреждение.
Типичная ошибка:
Обращение к несуществующему индексу $_SERVER['HTTP_USER_AGENT'] без проверки вызовет Warning.
Решение: всегда устанавливать значение по умолчанию.
Альтернативные варианты получения User-Agent
Как получить User-Agent через функцию getenv?
Функция getenv() позволяет прочитать переменную окружения, в которую веб-сервер (например, Apache) помещает заголовки. Вызов getenv('HTTP_USER_AGENT') вернёт строку или false при отсутствии.
<?php
$userAgent = getenv('HTTP_USER_AGENT') ?: 'Unknown';
echo $userAgent;
?>
App php domain (работа с доменами в php)
Замечание: На некоторых хостингах функция getenv() может быть отключена по соображениям безопасности. Этот способ менее предпочтителен, чем $_SERVER.
Возможная проблема:
Если getenv() возвращает false при отсутствии переменной, то код getenv('...') ?: '...' корректно подставит значение по умолчанию. Однако в некоторых окружениях getenv может возвращать пустую строку, которая в логическом контексте считается false - это так же обрабатывается.
Как безопасно получить User-Agent с фильтрацией?
Функция filter_input() предназначена для получения внешних переменных с возможностью фильтрации. Ей можно указать тип INPUT_SERVER и имя ключа HTTP_USER_AGENT.
<?php
$userAgent = filter_input(INPUT_SERVER, 'HTTP_USER_AGENT', FILTER_SANITIZE_STRING);
echo $userAgent;
?>
Http user agent php (получение user-agent в php)
Фильтр FILTER_SANITIZE_STRING удалит потенциально опасные символы. Однако это не гарантирует полную безопасность - для анализа User-Agent лучше использовать сырое значение.
Ограничения:
Если ключа нет, filter_input возвращает null (при отсутствии фильтра) или false (если фильтр не удался). Это может привести к путанице. Рекомендуется всегда явно проверять на null.
Как получить список всех HTTP-заголовков Apache?
Функция apache_request_headers() возвращает ассоциативный массив всех заголовков текущего запроса, включая User-Agent. Она доступна только при использовании модуля Apache mod_php.
<?php
$headers = apache_request_headers();
$userAgent = $headers['User-Agent'] ?? 'Unknown';
echo $userAgent;
?>
Обратите внимание: ключи массива могут быть написаны с разным регистром. В примере используется User-Agent (как в HTTP).
Особенности:
Функция не работает в режиме CGI/FastCGI или с другими веб-серверами (Nginx). Для Nginx есть аналог getallheaders(), но его включение зависит от настройки.
Общие проблемы при получении User-Agent
Помимо отсутствия самого заголовка, существуют и другие подводные камни:
- Подделка User-Agent. Злоумышленник может изменить строку User-Agent. Никогда не полагайтесь на неё для критической безопасности.
- Пустой User-Agent. Некоторые клиенты могут передавать пустое значение. Проверяйте длину строки.
- Пробелы и управляющие символы. Для предотвращения инъекций используйте trim() и проверку на валидность.
- Зависимость от окружения. В CLI-скриптах нет HTTP-заголовков - всегда подставляйте значение по умолчанию.
Расширенные примеры работы с User-Agent в PHP
Пример 1: Определение браузера и ОС на основе User-Agent (базовый парсинг)
Следующий код анализирует строку User-Agent и выводит название браузера и операционной системы. Для реального проекта рекомендуется использовать готовые библиотеки (например, Mobile Detect или WhichBrowser), но для демонстрации подойдёт упрощённая версия.
<?php
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
// Определение браузера
if (strpos($ua, 'Firefox') !== false) {
$browser = 'Firefox';
} elseif (strpos($ua, 'Chrome') !== false) {
$browser = 'Chrome';
} elseif (strpos($ua, 'Safari') !== false) {
$browser = 'Safari';
} else {
$browser = 'Unknown';
}
// Определение ОС
if (strpos($ua, 'Windows') !== false) {
$os = 'Windows';
} elseif (strpos($ua, 'Mac') !== false) {
$os = 'macOS';
} elseif (strpos($ua, 'Linux') !== false) {
$os = 'Linux';
} else {
$os = 'Unknown';
}
echo "Браузер: $browser, ОС: $os";
?>
Браузер: Chrome, ОС: macOS
Ошибка:
Такая проверка может дать ложное срабатывание, так как строка User-Agent содержит множество фрагментов. Например, Chrome может быть найден в строке даже при использовании другого браузера. Для точного парсинга стоит использовать готовые решения.
Пример 2: Логирование User-Agent с меткой времени
Запись полученного User-Agent в файл для аналитики.
<?php
$logFile = 'user_agents.log';
$ua = $_SERVER['HTTP_USER_AGENT'] ?? 'CLI/Unknown';
$time = date('Y-m-d H:i:s');
$entry = "[$time] $ua" . PHP_EOL;
file_put_contents($logFile, $entry, FILE_APPEND | LOCK_EX);
echo 'User-Agent записан в лог.';
?>
Результат в файле user_agents.log:
[2025-04-12 14:22:33] Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ...
Пример 3: Использование User-Agent для отдачи разного контента
Например, показывать упрощённую версию сайта старым браузерам.
<?php
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
if (preg_match('/MSIE|Trident/i', $ua)) {
// Internet Explorer
$layout = 'legacy';
} else {
$layout = 'modern';
}
echo "Выбран шаблон: $layout";
?>
Выбран шаблон: modern
Пример 4: Получение User-Agent через stream_context_get_default()
Этот способ нестандартный и редко используется, но может пригодиться для извлечения заголовков внутри обёртки потока.
<?php
$context = stream_context_get_default();
$options = stream_context_get_options($context);
$ua = $options['http']['header']['User-Agent'] ?? 'Unknown';
echo $ua;
?>
Однако такой подход работает только если контекст был предварительно задан (например, при создании потока). В обычном запросе он, скорее всего, не даст результата.
Ограничение:
В большинстве случаев stream_context_get_options возвращает пустой массив. Этот пример приведён больше для демонстрации возможностей PHP.
Пример 5: Получение User-Agent в консольном скрипте
При запуске скрипта из командной строки заголовки HTTP отсутствуют. Показан способ корректной обработки.
<?php
$isCli = php_sapi_name() === 'cli';
$ua = $isCli ? 'CLI' : ($_SERVER['HTTP_USER_AGENT'] ?? 'Unknown');
echo "User-Agent: $ua";
?>
User-Agent: CLI
Этот код проверяет, выполняется ли скрипт в CLI, и подставляет соответствующее значение.