小编典典

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

all

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

{a:1}

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

var_dump($_POST);

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


阅读 76

收藏
2022-04-01

共1个答案

小编典典

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

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

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

$entityBody = stream_get_contents(STDIN);

I/O 流 文档 的 PHP 手册条目中:

php://input 是一个只读流,允许您从请求正文中读取原始数据。在 POST 请求的情况下,最好使用 php://input
而不是$HTTP_RAW_POST_DATA因为它不依赖于特殊的 php.ini 指令。此外,对于那些
$HTTP_RAW_POST_DATA默认情况下未填充的情况,它可能是激活 always_populate_raw_post_data
的内存密集型替代方案。 php://input 不适用于 enctype=”multipart/form-data”。

具体来说,您需要注意php://input流,无论您如何在 Web 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://input 不适用于指定Content-Type: multipart/form- data标头(enctype="multipart/form-data"在 HTML 表单中)的请求。这是因为 PHP
已经将表单数据解析为$_POST超全局变量。

2022-04-01