5

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

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

foo=bar

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

Array
(
    [foo] => bar
)

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


场景二发送application/json数据

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

{
    "foo": "bar"
}

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

但是,运行print_r($request->getBody()->getContents());返回正常:

{"foo":"bar"}


这是预期的行为吗?

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

getBody()->getContents()如果我们要发送,应该使用 Whileapplication/json吗?


附加信息:

请求对象是使用以下方法创建的:

$request = \Laminas\Diactoros\ServerRequestFactory::fromGlobals(
        $_SERVER, $_GET, $_POST, $_COOKIE, $_FILES
);
4

1 回答 1

9

邮件正文:

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

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

在这种情况下,当执行对服务器的请求时,请求主体数据(无论其数据类型如何)会自动以原始格式(字符串)写入php://input流。稍后可以通过调用StreamInterface::getContentsStreamInterface::__toStringStreamInterface::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;

解析体:

就 PSR-7 而言,解析后的主体是“将 PHP用作服务器端应用程序来满足 HTTP 请求”的应用程序的“特征” (与将 PHP 用作“HTTP 客户端”的应用程序相比) " ) - 参见PSR-7 元文档摘要。所以,解析后的bodyServerRequestInterface唯一的一个组件。

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

相关用例:

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

如果执行 POST 请求并且标头Content-Typemultipart/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) 会返回一个“有效”值。

资源:

于 2020-02-09T20:07:47.323 回答