Q & A: Как получить POST-переменные с помощью PHP на сервисе облачных функций Alibaba Cloud - PullRequest
0 голосов
/ 19 ноября 2018

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

<? 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. Это не сработало, как ожидалось - результат остается пустым.

Причина - основная технология. Облачная функция Alibaba Cloud Compute использует управляемую событиями библиотеку React PHP для обработки запросов (это можно проверить, проанализировав объект $request). Таким образом, массив $_POST пуст и нет "простого способа получить данные POST" .

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

"bar=lala&foo=bar"

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

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

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

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

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

Ответы [ 2 ]

0 голосов
/ 21 ноября 2018

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

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

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

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

function initializer($context) {

}

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

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

Еще раз спасибо и всего наилучшего,

Ralf

0 голосов
/ 20 ноября 2018

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

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

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

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

...