如何在PHP中获取POST的正文?

时间:2012-01-20 18:05:42

标签: php rest post

我作为POST提交到php页面以下内容:

{a:1}

这是请求的主体(POST请求) 在php中,我需要做些什么才能提取该值?

var_dump($_POST); 

不是解决方案,不起作用。

9 个答案:

答案 0 :(得分:467)

要访问POST或PUT请求(或任何其他HTTP方法)的实体主体:

$entityBody = file_get_contents('php://input');

此外,STDIN常量是php://input的已打开流,因此您可以执行以下操作:

$entityBody = stream_get_contents(STDIN);

来自PHP manual entry on I/O streamsdocs

  

php:// input 是一个只读流,允许您读取原始数据   来自请求机构。在POST请求的情况下,它是可取的   使用 php:// input 而不是$HTTP_RAW_POST_DATA,因为它没有   依赖于特殊的php.ini指令。而且,对于那些情况   默认情况下不会填充$HTTP_RAW_POST_DATA,它是潜在的   激活的内存密集程度较低   always_populate_raw_post_data。 php:// input 不可用   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是在使用临时文件之前要保留在内存中的最大数据量(以字节为单位)。

当然,除非您有充分的理由寻求输入流,否则您不应该在Web应用程序中使用此功能。一次读取HTTP请求实体主体通常就足够了 - 在您的应用程序找出要做的事情时,不要让客户整天等待。

请注意,php://输入不适用于指定Content-Type: multipart/form-data标头(HTML表单中为enctype="multipart/form-data")的请求。这是因为PHP已经将表单数据解析为$_POST超全局。

答案 1 :(得分:10)

$_POST的一个可能原因是请求不再是POST,而不是POST ......它可能已经开始作为帖子,但遇到了{{ 1}}或301重定向某处,切换为302

检查GET以检查是否是这种情况。

请参阅https://stackoverflow.com/a/19422232/109787,以便详细讨论为什么不应该这样做,但仍然如此。

答案 2 :(得分:3)

答案 3 :(得分:3)

如果您已安装HTTP PECL扩展,则可以使用http_get_request_body()函数将正文数据作为字符串。

答案 4 :(得分:3)

这是一个如何使用 file_get_contents("php://input") 创建 php api 并在 javascript 中使用 ajaxXMLHttpRequest 的示例。

var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function () {
        if (this.readyState == 4 && this.status == 200) {
    console.log("done");
            }
        }
    };
    xhttp.open("POST", "http://127.0.0.1:8000/api.php", true);
    xhttp.send(JSON.stringify({
        username: $(this).val(),
        email:email,
        password:password
    }));

$data = json_decode(file_get_contents("php://input"));
$username  =  $data->username;
$email  =   $data->email;
$password  =   $data->password;

答案 5 :(得分:2)

如果您安装了pecl/http扩展程序,也可以使用:

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

答案 6 :(得分:2)

返回数组中的值

 $data = json_decode(file_get_contents('php://input'), true);

答案 7 :(得分:1)

http_get_request_body()是根据文档http://php.net/manual/fa/function.http-get-request-body.php

的明确提出的,用于获取PUTPOST请求的正文

答案 8 :(得分:0)

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());