Я отправляю как POST на страницу php следующее:
{a:1}
Это тело запроса (запрос POST).
В php, что мне нужно сделать, чтобы извлечь это значение?
var_dump($_POST);
это не решение, не работает.
Я отправляю как POST на страницу php следующее:
{a:1}
Это тело запроса (запрос POST).
В php, что мне нужно сделать, чтобы извлечь это значение?
var_dump($_POST);
это не решение, не работает.
Ответы:
Чтобы получить доступ к телу объекта запроса POST или PUT (или любого другого метода HTTP):
$entityBody = file_get_contents('php://input');
Кроме того, STDIN
константа является уже открытым потоком php://input
, так что вы можете сделать следующее:
$entityBody = stream_get_contents(STDIN);
Из руководства по PHP для документации потоков ввода / вывода :
php: // input - это поток только для чтения, который позволяет вам читать необработанные данные из тела запроса. В случае запросов POST предпочтительно использовать ввод php: // вместо того,
$HTTP_RAW_POST_DATA
чтобы не зависеть от специальных директив php.ini. Более того, для тех случаев, когда$HTTP_RAW_POST_DATA
по умолчанию не заполняется, это потенциально менее ресурсоемкая альтернатива активации always_populate_raw_post_data. php: // ввод недоступен с enctype = "multipart / form-data".
В частности, вы должны заметить, что 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: // input недоступен для запросов, указывающих Content-Type: multipart/form-data
заголовок ( enctype="multipart/form-data"
в HTML-формах). Это результат того, что PHP уже проанализировал данные формы в $_POST
суперглобальном.
php://input
пусто для application/x-www-form-urlencoded
типа контента (кроме multipart/form-data
)
php://input
есть. Так что пока (быстро) конфигурации CGI stream_get_contents(STDIN)
не будут работать, file_get_contents("php://input")
будет.
возвращаемое значение в массиве
$data = json_decode(file_get_contents('php://input'), true);
$data
ассоциативный массив, чтобы проверить, закодировано ли каждое значение так, как вы хотите. Взгляд на поток с типом данных может быть упрощенным, но он может быть не таким эффективным, как работа с кодированием в «потоковой форме» с использованием потокового фильтра. Если вы не решаете проблемы с кодированием, а просто очищаете и проверяете, вы пропускаете шаг.
Возможная причина пустого $_POST
заключается в том, что запрос не является POST
, или нет POST
больше ... Возможно, он начинался как пост, но где-то встретил 301
или 302
перенаправил, который переключен на GET
!
Осмотрите, $_SERVER['REQUEST_METHOD']
чтобы проверить, так ли это.
См. Https://stackoverflow.com/a/19422232/109787 для хорошего обсуждения того, почему это не должно происходить, но все же происходит.
POST
но после проверки она показала, что это так GET
. Как только я добавил /
в конце своего URL, он начал показывать POST. Weird!
Проверьте $HTTP_RAW_POST_DATA
переменную
php://input
. $HTTP_RAW_POST_DATA
недоступно с enctype="multipart/form-data"
.
Если вы установили расширение HTTP PECL, вы можете использовать http_get_request_body()
функцию для получения данных тела в виде строки.
Если у вас установлено расширение pecl / http , вы также можете использовать это:
$request = new http\Env\Request();
$request->getBody();
function getPost()
{
if(!empty($_POST))
{
// when using application/x-www-form-urlencoded or multipart/form-data as the HTTP Content-Type in the request
// NOTE: if this is the case and $_POST is empty, check the variables_order in php.ini! - it must contain the letter P
return $_POST;
}
// when using application/json as the HTTP Content-Type in the request
$post = json_decode(file_get_contents('php://input'), true);
if(json_last_error() == JSON_ERROR_NONE)
{
return $post;
}
return [];
}
print_r(getPost());
json_last_error() == JSON_ERROR_NONE
есть false
, что пустой массив должен быть возвращен. Что если кто-то отправил XML или YAML? Добавьте тест для Content-Type и перейдите оттуда.
$_SERVER
superglobal для полезных значений для проверки.
http_get_request_body()
был явно сделан для получения тела PUT
и POST
запросов согласно документации http://php.net/manual/fa/function.http-get-request-body.php
$_POST
суперглобальный объект. Это также (особенно) верно в случае запросов PUT, поскольку в PHP нет соответствующего суперглобального.