0

我在阿里云函数计算上使用了 PHP 7.2 运行时和 HTTP 触发器。文档中的基本示例如下:

<? php
use RingCentral\Psr7\Response;
function handler($request, $context): Response{
    /*
    $body       = $request->getBody()->getContents();
    $queries    = $request->getQueryParams();
    $method     = $request->getMethod();
    $headers    = $request->getHeaders();
    $path       = $request->getAttribute("path");
    $requestURI = $request->getAttribute("requestURI");
    $clientIP   = $request->getAttribute("clientIP");
    */
    return new Response(
        200,
        array(
            "custom_header1" => "v1"            
        ),
        "hello world"
    );
}

这工作得很好。从 URL 中获取查询参数很容易。但是正文内容仅在整个字符串中可用

$request->getBody()->getContents();

虽然文档说该$request参数遵循 PSR-7 HTTP 消息标准,但不能$request->getParsedBody()用于传递 POST 方法提交的值。它没有按预期工作 - 结果仍然是空的。

原因在于底层技术。阿里云函数计算使用事件驱动的 React PHP 库来处理请求(你可以通过分析$request对象来检查)。所以$_POST数组是空的,没有“获取 POST 数据的简单方法”

幸运的是,阿里巴巴的函数计算处理程序以字符串形式提供正文内容,$request->getBody()->getContents();例如

"bar=lala&foo=bar"

所以一个解决方案似乎比一开始想象的要容易,你可以使用 PHP 自己的parse_str()函数:

$data = [];
$body = $request->getBody()->getContents();
parse_str($body,$data);

如果将此片段放在处理程序函数中,则 POST 变量将存储在$data数组中并准备好进行进一步处理。

希望这可以帮助那些提出与我相同问题的人。:-)

亲切的问候,拉尔夫

4

2 回答 2

0

正如您在文档中看到的,您需要添加一个RequestBodyParserMiddlewareas 中间件来获取已解析的 PSR-7 请求。看来你没有这样做。

另请记住,此处仅支持Content-Types:application/x-www-form-urlencoded和。multipart/form-data因此,请确保客户端需要发送这些标头,以便可以解析请求。如果它是另一个 Content-Type 你需要使用另一个中间件。

有关更多信息,请参阅:https ://github.com/reactphp/http#requestbodyparsermiddleware。

我希望这有帮助!

于 2018-11-20T14:31:46.240 回答
0

@legionth:很抱歉我没有在这里使用评论功能,但我的回答太长了。:-) 非常感谢您的评论 -RequestBodyParserMiddleware如果您可以控制服务器代码,那么使用 是一个很好的解决方案。但在阿里云函数计算服务的背景下,这似乎是不可能的。我试图找出有关调用过程的更多信息 - 这是我的结果:

server.phpaReact\Http\Server中由以下方式开始:

$server = new Server(function (ServerRequestInterface $request) {

[...]

});

[...]

$socket = new \React\Socket\Server(sprintf('0.0.0.0:%s', $port), $loop);
$server->listen($socket);

$loop->run();

正如函数计算文档(& FC 控制台示例)中所见,我只能使用两个函数:

/*
if you open the initializer feature, please implement the initializer function, as below:
*/

function initializer($context) {

}

以及handler您可以在我的第一篇文章中找到的功能。

也许阿里巴巴未来会扩展 PHP 运行时,让使用自定义中间件成为可能,但目前我还没有找到办法。

再次感谢和亲切的问候,

拉尔夫

于 2018-11-21T12:45:29.103 回答