PSR-7: getParsedBody () против getBody () - PullRequest
       89

PSR-7: getParsedBody () против getBody ()

0 голосов
/ 06 февраля 2020

Сценарий 1 отправка x-www-form-urlencoded данных

POST /path HTTP/1.1
Content-Type: application/x-www-form-urlencoded

foo=bar

Выполнение print_r($request->getParsedBody()); возвращает отлично:

Array
(
    [foo] => bar
)

Выполнение print_r($request->getBody()->getContents()); возвращает строку foo=bar


Сценарий 2 отправка application/json данных

POST /path HTTP/1.1
Content-Type: application/json

{
    "foo": "bar"
}

Выполнение print_r($request->getParsedBody()); возвращает пустой массив. Array ( )

Но при работе print_r($request->getBody()->getContents()); возвращается нормально:

{"foo":"bar"}


Это ожидаемое поведение?

Значение, если мы отправляем x-www-form-urlencoded данных, мы должны использовать getParsedBody().

, тогда как getBody()->getContents() следует использовать, если мы отправляем application/json?


Дополнительная информация:

Объект запроса создан с использованием:

$request = \Laminas\Diactoros\ServerRequestFactory::fromGlobals(
        $_SERVER, $_GET, $_POST, $_COOKIE, $_FILES
);

1 Ответ

1 голос
/ 09 февраля 2020

Тело сообщения:

В библиотеке PSR-7 тело сообщения абстрагируется от StreamInterface. Любая реализация этого интерфейса ДОЛЖНА обернуть поток PHP stream и, конечно, должна обеспечивать надлежащие функциональные возможности для выполнения на нем определенных операций c чтения / записи / поиска. PHP предоставляет список потоков ввода-вывода потоков , из которых php://input подходит для рассматриваемой задачи.

php://input - поток только для чтения, который позволяет читать необработанные данные из тела запроса.
php://input недоступно с enctype = "multipart / form-data" .

В этом контексте, когда выполняется запрос к серверу, запрос Данные тела (независимо от их типа данных) автоматически записываются в поток php://input в необработанном формате (строка). Позже информацию можно прочитать из нее, вызвав StreamInterface::getContents, StreamInterface::__toString или StreamInterface::read (что, вероятно, будет использовать stream_get_contents() или подобное в их реализации).

Анализируемое тело:

Что касается PSR-7, проанализированное тело является "характеристикой c" приложений, где PHP равно «используется как серверное приложение для выполнения HTTP-запросов» (по сравнению с приложениями, в которых *1137* используется как «HTTP-клиент» ) - см. Сводка Мета-документ PSR-7 . Таким образом, проанализированное тело является компонентом только ServerRequestInterface.

проанализированное тело (см. Комментарии ServerRequestInterface::getParsedBody и ServerRequestInterface::withParsedBody) рассматривается как представление необработанных данных (строк), сохраненных в потоке php://input (в результате выполнения запроса) в «разобранной» форме (массив или объект). Например, переменная $ _ POST содержит проанализированное тело запроса POST при следующих условиях.

Соответствующие варианты использования:

Если выполняется запрос POST и заголовок Content-Type равен application/x-www-form-urlencoded (например, при отправке обычной формы HTML), содержимое Тело запроса автоматически сохраняется как в потоке php://input (сериализовано), так и в переменную $ _POST (массив). Таким образом, в контексте PSR-7 вызов и StreamInterface::getContents (или StreamInterface::__toString, или StreamInterface::read) и ServerRequestInterface::getParsedBody вернет "допустимые" значения.

Если выполняется запрос POST и заголовок Content-Type равен multipart/form-data (например, при выполнении загрузки файла) содержимое тела запроса вообще НЕ сохраняется в потоке php://input, а только в переменную $ _POST (массив). Таким образом, в контексте PSR-7 только вызов ServerRequestInterface::getParsedBody вернет «допустимое» значение.

Если выполняется запрос POST и заголовок Content-Type имеет другое значение, чем два, представленных выше (для Например, application/json, или text/plain; charset=utf-8), содержимое тела запроса сохраняется только в поток php://input. Таким образом, в контексте PSR-7 только вызов StreamInterface::getContents (или StreamInterface::__toString, или StreamInterface::read) вернет "допустимое" значение.

Ресурсы:

...