← Назад к вопросам

Как разделить заголовок и тело запроса?

2.0 Middle🔥 122 комментариев
#API и веб-протоколы

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разделение заголовков и тела HTTP-запроса в PHP

В PHP заголовки и тело HTTP-запроса разделяются автоматически системой, но разработчику важно понимать, как к ним обращаться и работать с ними в разных контекстах. Это фундаментальный аспект работы с HTTP в веб-разработке.

Основные подходы к разделению

1. Автоматическое разделение через суперглобальные массивы

PHP автоматически парсит входящие HTTP-запросы и разделяет данные между суперглобальными массивами:

<?php
// Заголовки доступны через $_SERVER (с префиксом HTTP_) и getallheaders()
$headers = getallheaders();
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? null;
$contentType = $_SERVER['CONTENT_TYPE'] ?? null;

// Тело запроса доступно через различные суперглобальные в зависимости от метода
$getData = $_GET;     // Для GET-параметров в URL
$postData = $_POST;   // Для application/x-www-form-urlencoded или multipart/form-data
$inputData = file_get_contents('php://input'); // Для чтения raw тела запроса
?>

2. Работа с raw HTTP-запросом

Для низкоуровневой работы или нестандартных форматов можно читать весь запрос и парсить вручную:

<?php
// Чтение всего HTTP-запроса
$rawRequest = file_get_contents('php://input');

// Пример ручного парсинга (упрощенный)
$lines = explode("\r\n", $rawRequest);
$headers = [];
$body = '';
$isBody = false;

foreach ($lines as $line) {
    if ($line === '') {
        $isBody = true;
        continue;
    }
    
    if (!$isBody) {
        $headers[] = $line;
    } else {
        $body .= $line;
    }
}

// Использование встроенных функций для парсинга заголовков
$parsedHeaders = [];
foreach ($headers as $header) {
    if (strpos($header, ':') !== false) {
        list($key, $value) = explode(':', $header, 2);
        $parsedHeaders[trim($key)] = trim($value);
    }
}
?>

3. Современный подход с PSR-7 и фреймворками

В современных приложениях часто используют стандарт PSR-7 или фреймворки:

<?php
// Пример с использованием PSR-7 (Guzzle)
use GuzzleHttp\Psr7\ServerRequest;

$request = ServerRequest::fromGlobals();
$headers = $request->getHeaders();
$body = $request->getBody()->getContents();

// Laravel подход
$headers = request()->headers->all();
$body = request()->getContent();

// Symfony подход
use Symfony\Component\HttpFoundation\Request;

$request = Request::createFromGlobals();
$headers = $request->headers->all();
$body = $request->getContent();
?>

Ключевые технические моменты

Разделитель заголовков и тела: В HTTP-протоколе заголовки отделяются от тела двумя символами перевода строки (\r\n\r\n). Это критически важный разделитель, который определяет границу между метаданными и содержимым запроса.

Типы контента и обработка тела:

  • Для application/x-www-form-urlencoded данные автоматически парсятся в $_POST
  • Для multipart/form-data (загрузка файлов) данные также попадают в $_POST и $_FILES
  • Для application/json, application/xml или других форматов используйте php://input

Особенности работы с php://input:

  • Этот поток можно прочитать только один раз
  • Недоступен для enctype="multipart/form-data"
  • Содержит "сырое" тело запроса после заголовков

Практические рекомендации

  1. Используйте соответствующие методы для разных форматов:

    <?php
    function parseRequest() {
        $contentType = $_SERVER['CONTENT_TYPE'] ?? '';
        
        if (strpos($contentType, 'application/json') !== false) {
            return json_decode(file_get_contents('php://input'), true);
        } elseif (strpos($contentType, 'application/x-www-form-urlencoded') !== false) {
            return $_POST;
        } elseif (strpos($contentType, 'multipart/form-data') !== false) {
            return ['post' => $_POST, 'files' => $_FILES];
        }
        
        return file_get_contents('php://input');
    }
    ?>
    
  2. Безопасность при обработке заголовков:

    • Всегда проверяйте и фильтруйте заголовки
    • Не доверяйте пользовательским заголовкам
    • Используйте встроенные функции для безопасного извлечения данных
  3. Производительность:

    • Для больших тел запросов используйте потоковое чтение
    • Кэшируйте результаты парсинга при необходимости
    • Избегайте многократного чтения php://input

Разделение заголовков и тела - базовая, но критически важная операция в обработке HTTP-запросов. Понимание этого процесса позволяет корректно работать с различными типами запросов, правильно обрабатывать файлы, JSON, XML и другие форматы данных, а также обеспечивать безопасность и производительность приложения.