Этот документ описывает общие интерфейсы для представления HTTP сообщений, как описано в RFC 7230 и RFC 7231, и URI для использования с сообщениями HTTP, как описано в RFC 3986.
HTTP-сообщения являются основой веб-разработки. Веб-браузеры и HTTP-клиенты, такие как cURL, создают HTTP-запрос, который отправляется на веб-сервер, предоставляющий HTTP-ответ. Серверный код получает HTTP-запрос и возвращает ответное сообщение HTTP.
Сообщения HTTP обычно абстрагируются от конечного потребителя, но как разработчики, мы как правило должны знать, как они структурированы и как получить доступ к ним или манипулировать ими для выполнения наших задач, будь то выполнение запроса к HTTP API или обработка входящего запроса.
Каждое сообщение HTTP-запроса имеет определенную форму:
POST /path HTTP/1.1 Host: example.com foo=bar&baz=bat
Первая строка запроса является «строкой запроса» и содержит по порядку метод HTTP-запроса, целевой объект запроса (обычно либо абсолютный URI, либо путь на веб-сервере) и версию протокола HTTP. Далее следует один или несколько заголовков HTTP, пустая строка и текст сообщения.
Ответные сообщения HTTP имеют схожую структуру:
HTTP/1.1 200 OK Content-Type: text/plain This is the response body
Первая строка является «строкой состояния» и содержит по порядку версию протокола HTTP, код состояния HTTP и «формулировка причины» - удобочитаемое описание кода состояния. Как и сообщение запроса, за ним следует один или несколько заголовков HTTP, пустая строка и тело сообщения.
Интерфейсы, описанные в этом документе, являются абстракциями вокруг HTTP-сообщений и составляющих их элементов.
Ключевые слова 'ДОЛЖНЫ', 'НЕ ДОЛЖНЫ', 'ТРЕБУЕТСЯ', 'НУЖНО', 'НЕ НУЖНО', 'СЛЕДУЕТ', 'НЕ СЛЕДУЕТ', 'РЕКОМЕНДУЕТСЯ', 'МОЖЕТ' и 'НЕОБЯЗАТЕЛЬНО' в этом документе должны толковаться так, как описано в RFC 2119.
HTTP-сообщение - это либо запрос от клиента к серверу, либо ответ от сервера клиенту. Это описание определяет интерфейсы для сообщений HTTP Psr\Http\Message\RequestInterface и Psr\Http\Message\ResponseInterface соответственно.
Оба интерфейса Psr\Http\Message\RequestInterface и Psr\Http\Message\ResponseInterface расширяют Psr\Http\Message\MessageInterface. В то время как интерфейс Psr\Http\Message\MessageInterface МОЖЕТ быть реализован напрямую, разработчики ДОЛЖНЫ реализовать интерфейсы Psr\Http\Message\RequestInterface и Psr\Http\Message\ResponseInterface.
В дальнейшем пространство имен Psr\Http\Message будет опущено при обращении к этим интерфейсам.
Имена полей заголовка без учета регистра
HTTP-сообщения содержат имена полей заголовка без учета регистра. Заголовки извлекаются по имени из классов, реализующих интерфейс MessageInterface без учета регистра. Например, извлечение заголовка foo вернет тот же результат, что и извлечение заголовка FoO. Аналогично, установка заголовка Foo перезапишет любое ранее установленное значение заголовка в foo.
$message = $message->withHeader('foo', 'bar'); echo $message->getHeaderLine('foo'); // Выведет: bar echo $message->getHeaderLine('FOO'); // Выведет: bar $message = $message->withHeader('fOO', 'baz'); echo $message->getHeaderLine('foo'); // Выведет: baz
Несмотря на то, что заголовки могут быть получены без учета регистра, исходный регистр ДОЛЖЕН быть сохранен реализацией, в частности, при получении с помощью getHeaders().
Несоответствующие HTTP-приложения могут зависеть от определенного случая, поэтому пользователю полезно иметь возможность диктовать регистр HTTP-заголовков при создании запроса или ответа.
Заголовки с несколькими значениями
Чтобы разместить заголовки с несколькими значениями, но при этом обеспечить удобство работы с заголовками в виде строк, заголовки могут быть извлечены из экземпляра MessageInterface в виде массива или строки. Используйте метод getHeaderLine() для получения значения заголовка в виде строки, содержащей все значения заголовка без учета регистра имени, перечисленныые через запятую. Используйте getHeader(), чтобы по имени заголовка, получить массив всех значений конкретного заголовка нечувствительного к регистру.
$message = $message ->withHeader('foo', 'bar') ->withAddedHeader('foo', 'baz'); $header = $message->getHeaderLine('foo'); // $header содержит: 'bar,baz' $header = $message->getHeader('foo'); // ['bar', 'baz']
Примечание: не все значения заголовка могут быть объединены с помощью запятой (например, Set-Cookie). При работе с такими заголовками потребители классов основанных на MessageInterface ДОЛЖНЫ полагаться на метод getHeader() для извлечения таких многозначных заголовков.
В запросах, заголовок Host, обычно отражает хостовую часть от URI, а также хост, используемый при установлении TCP-соединения. Однако, спецификация HTTP для каждого из них позволяет заголовку Host отличаться.
Если заголовок Host не установлен, то во время создания, реализация ДОЛЖНА попытаться установить заголовок Host из предоставленного URI.
RequestInterface::withUri() по умолчанию заменит заголовок Host возвращаемого запроса, на заголовок c Host соответствующего части хоста переданного из UriInterface.