Ответ 1
Чтобы получить доступ к сущности тела запроса POST или PUT (или любого другого метода HTTP):
$entityBody = file_get_contents('php://input');
Кроме того, константа STDIN
является уже открытым потоком до php://input
, поэтому вы можете также:
$entityBody = stream_get_contents(STDIN);
Из Ручная запись PHP в потоках ввода-вывода docs:
php://input - поток, доступный только для чтения, который позволяет вам читать исходные данные от органа запроса. В случае запросов POST предпочтительнее использовать php://ввод вместо
$HTTP_RAW_POST_DATA
, поскольку он не зависят от специальных директив php.ini. Более того, для тех случаев, когда$HTTP_RAW_POST_DATA
по умолчанию не заполняется, это потенциально менее энергоемкая альтернатива активации always_populate_raw_post_data. php://ввод недоступен с ENCTYPE = "многочастному/форм-данных".
В частности, вы хотите отметить, что поток php://input
, независимо от того, как вы обращаетесь к нему в веб-SAPI, не доступен для поиска. Это означает, что его можно прочитать только один раз. Если вы работаете в среде, где обычно загружаются большие тела объектов HTTP, вы можете сохранить ввод в форме потока (а не буферизировать его, как в первом примере выше).
Для поддержания ресурса потока может быть полезно что-то вроде этого:
<?php
function detectRequestBody() {
$rawInput = fopen('php://input', 'r');
$tempStream = fopen('php://temp', 'r+');
stream_copy_to_stream($rawInput, $tempStream);
rewind($tempStream);
return $tempStream;
}
php://temp
позволяет вам управлять потреблением памяти, поскольку он будет прозрачно переключаться на хранилище файловой системы после хранения определенного объема данных (по умолчанию 2M). Этот размер можно обрабатывать в файле php.ini или путем добавления /maxmemory:NN
, где NN
- это максимальный объем данных для хранения в памяти перед использованием временного файла в байтах.
Конечно, если у вас нет действительно веских оснований для поиска входного потока, вам не нужна эта функциональность в веб-приложении. Чтение тела объекта запроса HTTP один раз обычно достаточно - не заставляйте клиентов ждать весь день, пока ваше приложение выясняет, что делать.
Обратите внимание, что вход php://недоступен для запросов, определяющих заголовок Content-Type: multipart/form-data
(enctype="multipart/form-data"
в HTML-формах). Это связано с тем, что PHP уже проанализировал данные формы в суперглобальном $_POST
.