actQ & A: Как получить переменные POST с помощью PHP в сервисе облачных функций Alibaba Cloud Function

Я поиграл с исполняемой версией PHP 7.2 и триггером HTTP на Alibaba Cloud Function Compute. Основной пример в документации следующий:

<? 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 параметр соответствует стандарту HTTP-сообщения PSR-7, его невозможно использовать $request->getParsedBody() доставить значения, представленные методом POST. Это не сработало, как ожидалось — результат остается пустым.

Причина в базовой технологии. Cloud Function Compute в Alibaba использует управляемую событиями библиотеку React PHP для обработки запросов (это можно проверить, проанализировав $request объект). Итак $_POST массив пуст и нет «простой способ получить данные POST».

К счастью, обработчик функций Alibaba Function Compute предоставляет содержимое тела $request->getBody()->getContents(); как строка

"bar=lala&foo=bar"

Таким образом, решение кажется проще, чем предполагалось в начале, вы можете, например, использовать собственный PHP parse_str() функция:

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

Если вы поместите этот фрагмент в функцию-обработчик, переменные POST будут сохранены в $data массив и готов к дальнейшей обработке.

Надеюсь, что это поможет кому-то, кто задавал те же вопросы, что и я 🙂

С уважением,
Ralf

0

Решение

Как вы можете видеть в документации, вам нужно добавить RequestBodyParserMiddleware в качестве промежуточного программного обеспечения для получения проанализированного запроса PSR-7. Кажется, ты этого не делал.

Также имейте в виду, что только Content-Types: application/x-www-form-urlencoded а также multipart/form-data поддерживаются здесь. Поэтому убедитесь, что клиент должен отправить эти заголовки, чтобы запрос мог быть проанализирован. Если это другой тип контента, вам нужно использовать другое промежуточное ПО.

Увидеть: https://github.com/reactphp/http#requestbodyparsermiddleware для дополнительной информации.

Надеюсь, это поможет!

0

Другие решения

@legionth: Я извиняюсь, что не использовал здесь функцию комментариев, но мой ответ слишком длинный. 🙂
Большое спасибо за ваши комментарии — использование RequestBodyParserMiddleware отличное решение, если вы можете контролировать код сервера. Но в контексте службы облачных вычислений Alibaba это кажется невозможным. Я попытался узнать больше информации о процессе вызова — вот мои результаты:

В server.php React\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();

Как видно из функции Compute документация (& Пример консоли FC), я могу использовать только две функции:

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

function initializer($context) {

}

и handler функцию вы можете найти в моем первом посте.

Возможно, в будущем Alibaba расширит среду выполнения PHP, чтобы можно было использовать пользовательское промежуточное ПО, но в настоящее время я не нашел способа сделать это.

еще раз спасибо & С уважением,

Ralf

0