PSR-7:getParsedBody() 与 getBody()
PSR-7: getParsedBody() vs getBody()
场景 1 发送 x-www-form-urlencoded
数据
POST /path HTTP/1.1
Content-Type: application/x-www-form-urlencoded
foo=bar
运行 print_r($request->getParsedBody());
returns 很好:
Array
(
[foo] => bar
)
运行 print_r($request->getBody()->getContents());
returns 一个字符串 foo=bar
场景2发送application/json
数据
POST /path HTTP/1.1
Content-Type: application/json
{
"foo": "bar"
}
运行 print_r($request->getParsedBody());
returns 一个空数组。 Array ( )
但是,运行 print_r($request->getBody()->getContents());
returns 很好:
{"foo":"bar"}
这是预期的行为吗?
意思是,如果我们要发送 x-www-form-urlencoded
数据,我们应该使用 getParsedBody()
。
如果我们要发送 application/json
,则应使用 getBody()->getContents()
?
附加信息:
请求对象是使用以下方法创建的:
$request = \Laminas\Diactoros\ServerRequestFactory::fromGlobals(
$_SERVER, $_GET, $_POST, $_COOKIE, $_FILES
);
留言body:
在 PSR-7 库中,消息 body 由 StreamInterface
提取。此接口的任何实现必须包装一个 PHP stream and, of course, should provide the proper functionality to perform the specific read/write/seek operations on it. PHP provides a list of I/O streams,其中 php://input
适合所讨论的任务。
php://input
is a read-only stream that allows you to read raw data from the request body. php://input
is not available with enctype="multipart/form-data".
在此上下文中,当执行对服务器的请求时,请求 body 数据(无论其数据类型如何)自动写入 php://input
流,原始格式(字符串).稍后可以通过调用 StreamInterface::getContents
、StreamInterface::__toString
或 StreamInterface::read
(可能会在其实现中使用 stream_get_contents()
或类似方法)从中读取信息。
注:当object代表消息[=122]时,自动调用方法StreamInterface::__toString
=],例如class 实现 StreamInterface
的实例被转换为字符串。例如,像这样 - 参见 PHP 中的 Type Casting:
$messageBodyObject = $request->getBody(); // implements StreamInterface
$contentOfMessageBody = (string) $messageBodyObject; // cast to string => StreamInterface::__toString is called
echo $contentOfMessageBody;
已解析 body:
关于 PSR-7,解析的 body 是应用程序的“特征”,其中 PHP 是 “用作 server-side 应用程序来完成 HTTP 请求”(与 PHP 用作 “HTTP 客户端” 的应用程序相比) - 见 Summary of the PSR-7 Meta Document。所以,解析的body只是ServerRequestInterface
的一个组成部分。
解析的body(阅读ServerRequestInterface::getParsedBody
和ServerRequestInterface::withParsedBody
的注释)被认为是“解析”形式的表示作为执行请求的结果保存在 php://input
流中的原始数据(字符串)的(数组或 object)。例如,$_POST variable 是一个数组,它包含 已解析的 body POST 请求,在下面给出的条件下。
相关use-cases:
如果执行POST请求并且header Content-Type
是application/x-www-form-urlencoded
(例如当提交一个普通的HTML表单时),内容请求的 body 自动保存到 php://input
流(序列化)和 $_POST 变量(数组)中。因此,在 PSR-7 上下文中,同时调用 StreamInterface::getContents
(或 StreamInterface::__toString
,或 StreamInterface::read
)和 ServerRequestInterface::getParsedBody
将 return“有效”值。
如果执行 POST 请求并且 header Content-Type
为 multipart/form-data
(例如执行文件上传时),则请求 body 根本不会保存到 php://input
流中,而只会保存到 $_POST 变量(数组)中。因此,在 PSR-7 上下文中,只有调用 ServerRequestInterface::getParsedBody
才会 return 一个“有效”值。
如果执行了 POST 请求,并且 header Content-Type
具有除上述两个之外的其他值(例如 application/json
,或 text/plain; charset=utf-8
),请求 body 的内容仅保存到 php://input
流中。因此,在 PSR-7 上下文中,仅调用 StreamInterface::getContents
(或 StreamInterface::__toString
或 StreamInterface::read
)将 return 一个“有效”值。
资源:
场景 1 发送 x-www-form-urlencoded
数据
POST /path HTTP/1.1
Content-Type: application/x-www-form-urlencoded
foo=bar
运行 print_r($request->getParsedBody());
returns 很好:
Array
(
[foo] => bar
)
运行 print_r($request->getBody()->getContents());
returns 一个字符串 foo=bar
场景2发送application/json
数据
POST /path HTTP/1.1
Content-Type: application/json
{
"foo": "bar"
}
运行 print_r($request->getParsedBody());
returns 一个空数组。 Array ( )
但是,运行 print_r($request->getBody()->getContents());
returns 很好:
{"foo":"bar"}
这是预期的行为吗?
意思是,如果我们要发送 x-www-form-urlencoded
数据,我们应该使用 getParsedBody()
。
如果我们要发送 application/json
,则应使用 getBody()->getContents()
?
附加信息:
请求对象是使用以下方法创建的:
$request = \Laminas\Diactoros\ServerRequestFactory::fromGlobals(
$_SERVER, $_GET, $_POST, $_COOKIE, $_FILES
);
留言body:
在 PSR-7 库中,消息 body 由 StreamInterface
提取。此接口的任何实现必须包装一个 PHP stream and, of course, should provide the proper functionality to perform the specific read/write/seek operations on it. PHP provides a list of I/O streams,其中 php://input
适合所讨论的任务。
php://input
is a read-only stream that allows you to read raw data from the request body.php://input
is not available with enctype="multipart/form-data".
在此上下文中,当执行对服务器的请求时,请求 body 数据(无论其数据类型如何)自动写入 php://input
流,原始格式(字符串).稍后可以通过调用 StreamInterface::getContents
、StreamInterface::__toString
或 StreamInterface::read
(可能会在其实现中使用 stream_get_contents()
或类似方法)从中读取信息。
注:当object代表消息[=122]时,自动调用方法StreamInterface::__toString
=],例如class 实现 StreamInterface
的实例被转换为字符串。例如,像这样 - 参见 PHP 中的 Type Casting:
$messageBodyObject = $request->getBody(); // implements StreamInterface
$contentOfMessageBody = (string) $messageBodyObject; // cast to string => StreamInterface::__toString is called
echo $contentOfMessageBody;
已解析 body:
关于 PSR-7,解析的 body 是应用程序的“特征”,其中 PHP 是 “用作 server-side 应用程序来完成 HTTP 请求”(与 PHP 用作 “HTTP 客户端” 的应用程序相比) - 见 Summary of the PSR-7 Meta Document。所以,解析的body只是ServerRequestInterface
的一个组成部分。
解析的body(阅读ServerRequestInterface::getParsedBody
和ServerRequestInterface::withParsedBody
的注释)被认为是“解析”形式的表示作为执行请求的结果保存在 php://input
流中的原始数据(字符串)的(数组或 object)。例如,$_POST variable 是一个数组,它包含 已解析的 body POST 请求,在下面给出的条件下。
相关use-cases:
如果执行POST请求并且header Content-Type
是application/x-www-form-urlencoded
(例如当提交一个普通的HTML表单时),内容请求的 body 自动保存到 php://input
流(序列化)和 $_POST 变量(数组)中。因此,在 PSR-7 上下文中,同时调用 StreamInterface::getContents
(或 StreamInterface::__toString
,或 StreamInterface::read
)和 ServerRequestInterface::getParsedBody
将 return“有效”值。
如果执行 POST 请求并且 header Content-Type
为 multipart/form-data
(例如执行文件上传时),则请求 body 根本不会保存到 php://input
流中,而只会保存到 $_POST 变量(数组)中。因此,在 PSR-7 上下文中,只有调用 ServerRequestInterface::getParsedBody
才会 return 一个“有效”值。
如果执行了 POST 请求,并且 header Content-Type
具有除上述两个之外的其他值(例如 application/json
,或 text/plain; charset=utf-8
),请求 body 的内容仅保存到 php://input
流中。因此,在 PSR-7 上下文中,仅调用 StreamInterface::getContents
(或 StreamInterface::__toString
或 StreamInterface::read
)将 return 一个“有效”值。
资源: