PSR-7:getParsedBody() 与 getBody()

IMB*_*IMB 6 php post json http-post psr-7

场景一发送x-www-form-urlencoded数据

POST /path HTTP/1.1
Content-Type: application/x-www-form-urlencoded

foo=bar
Run Code Online (Sandbox Code Playgroud)

运行print_r($request->getParsedBody());返回正常:

Array
(
    [foo] => bar
)
Run Code Online (Sandbox Code Playgroud)

运行print_r($request->getBody()->getContents());返回一个字符串foo=bar


场景2发送application/json数据

POST /path HTTP/1.1
Content-Type: application/json

{
    "foo": "bar"
}
Run Code Online (Sandbox Code Playgroud)

运行print_r($request->getParsedBody());返回一个空数组。Array ( )

但是,运行print_r($request->getBody()->getContents());效果很好:

{"foo":"bar"}


这是预期的行为吗?

这意味着,如果我们要发送x-www-form-urlencoded数据,我们应该使用getParsedBody().

getBody()->getContents()如果我们发送 application/json?则应使用while 。


附加信息:

请求对象是使用以下命令创建的:

$request = \Laminas\Diactoros\ServerRequestFactory::fromGlobals(
        $_SERVER, $_GET, $_POST, $_COOKIE, $_FILES
);
Run Code Online (Sandbox Code Playgroud)

dak*_*kis 11

邮件正文:

在 PSR-7 库中,消息正文由StreamInterface. 该接口的任何实现都必须包装PHP 流,当然,应该提供适当的功能来对其执行特定的读/写/查找操作。PHP 提供了一个 I/O流列表,其中php://input适合所讨论的任务。

php://input是一个只读流,允许您从请求正文中读取原始数据。php://input不适用于enctype="multipart/form-data"。

在此上下文中,当执行对服务器的请求时,请求正文数据(无论其数据类型如何)会自动php://input以原始格式(字符串)写入流。StreamInterface::getContents稍后可以通过调用、StreamInterface::__toString或来从中读取信息StreamInterface::read(在其实现中可能会使用stream_get_contents()或类似的函数)。

注意:StreamInterface::__toString当表示消息正文的对象(例如实现类的实例)转换StreamInterface为字符串该方法例如,像这样 - 请参阅PHP 中的类型转换:

$messageBodyObject = $request->getBody(); // implements StreamInterface
$contentOfMessageBody = (string) $messageBodyObject; // cast to string => StreamInterface::__toString is called

echo $contentOfMessageBody;
Run Code Online (Sandbox Code Playgroud)

解析后的正文:

对于 PSR-7,解析正文是 PHP “用作服务器端应用程序来完成 HTTP 请求”的应用程序的“特征” (与 PHP 用作“HTTP 客户端”的应用程序相比) ” ) - 请参阅PSR-7 元文档摘要。所以,解析后的主体是ServerRequestInterface唯一的一个组成部分。

解析的主体(阅读ServerRequestInterface::getParsedBody和 的注释)被认为是作为执行请求的结果ServerRequestInterface::withParsedBody保存在流中的原始数据(字符串)的“解析”形式(数组或对象)的表示。php://input例如,$_POST 变量是一个数组,在下面给出的条件下保存 POST 请求的解析正文。

相关用例:

如果执行 POST 请求且标头Content-Type为application/x-www-form-urlencoded(例如提交普通 HTML 表单时),则请求正文的内容会自动保存到流php://input(序列化)和 $_POST 变量(数组)中。因此,在 PSR-7 上下文中,调用StreamInterface::getContents(or StreamInterface::__toString、 or StreamInterface::read) 和ServerRequestInterface::getParsedBody将返回“有效”值。

如果执行 POST 请求并且标头Content-Type为multipart/form-data(例如执行文件上传时),则请求正文的内容根本不会保存到流中php://input,而只会保存到 $_POST 变量(数组)中。因此,在 PSR-7 上下文中,只有调用ServerRequestInterface::getParsedBody才会返回“有效”值。

如果执行 POST 请求并且标头Content-Type具有除上述两个值之外的其他值(例如application/json、 或text/plain; charset=utf-8),则请求正文的内容仅保存到流中php://input。因此,在 PSR-7 上下文中,只有调用StreamInterface::getContents(or StreamInterface::__toString、 or StreamInterface::read) 才会返回“有效”值。

资源: