Как получить тело POST в php?

Я отправлю как POST на страницу php следующее:

{a:1}

Это тело запроса (запрос POST).
В php, что мне нужно сделать, чтобы извлечь это значение?

var_dump($_POST); 

не является решением, а не работает.

Ответ 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.

Ответ 2

Возможная причина для пустого $_POST заключается в том, что запрос не является POST, а не POST больше... Возможно, он начинался как сообщение, но встречал перенаправление 301 или 302 где-то, что требуется для переключения на GET!

Осмотрите $_SERVER['REQUEST_METHOD'], чтобы убедиться, что это так.

Ответ 4

Если вы установили расширение HTTP PECL, вы можете использовать функцию http_get_request_body(), чтобы получить данные тела в виде строки.

Ответ 5

Если у вас установлено расширение pecl/http, вы также можете использовать это:

$request = new http\Env\Request();
$request->getBody();