Как получить тело отправленных данных с помощью Guzzle PHP?

Я использую Guzzle (v6.1.1) в PHP сделать запрос POST на сервер. Работает отлично. Я добавляю некоторые функции ведения журнала для регистрации того, что было отправлено и получено, и я не могу понять, как получить данные, которые отправлены на сервер. Я могу получить ответ просто отлично, но как я могу получить отправлено данные? (Это будет строка JSON.)

вот соответствующая часть моего кода:

$client = new GuzzleHttpClient(['base_uri' => $serviceUrlPayments ]);
    try {
       $response = $client->request('POST', 'Charge', [
            'auth' => [$securenetId, $secureKey],
            'json' => [     "amount" => $amount,
                            "paymentVaultToken" => array(
                                    "customerId" => $customerId,
                                    "paymentMethodId" => $token,
                                    "publicKey" => $publicKey
                                    ),
                            "extendedInformation" => array(
                                    "typeOfGoods" => $typeOfGoods,
                                    "userDefinedFields" => $udfs,
                                    "notes" => $Notes
                                    ),
                            'developerApplication'=> $developerApplication 
            ]
    ]);

    } catch (ServerErrorResponseException $e) {
        echo (string) $e->getResponse()->getBody();
    }


    echo $response->getBody(); // THIS CORRECTLY SHOWS THE SERVER RESPONSE
    echo $client->getBody();           // This doesn't work
    echo $client->request->getBody();  // nor does this

любая помощь будет оценили. Я пытался заглянуть внутрь. Guzzle sourcecode для функции, подобной getBody (), которая будет работать с запросом, но я не эксперт PHP, поэтому я не придумал ничего полезного. Я также много искал Google, но нашел только людей, говорящих о получении ответа от сервера, с которым у меня нет проблем.

3 ответов


Вы можете сделать эту работу, создав промежуточное.

use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use Psr\Http\Message\RequestInterface;

$stack = HandlerStack::create();
// my middleware
$stack->push(Middleware::mapRequest(function (RequestInterface $request) {
    $contentsRequest = (string) $request->getBody();
    //var_dump($contentsRequest);

    return $request;
}));

$client = new Client([
    'base_uri' => 'http://www.example.com/api/',
    'handler' => $stack
]);

$response = $client->request('POST', 'itemupdate', [
    'auth' => [$username, $password],
    'json' => [
        "key" => "value",
        "key2" => "value",
    ]
]);

это, однако, запускается до получения ответа. Вы можете сделать что-то вроде этого:

$stack->push(function (callable $handler) {
    return function (RequestInterface $request, array $options) use ($handler) {
        return $handler($request, $options)->then(
            function ($response) use ($request) {
                // work here
                $contentsRequest = (string) $request->getBody();
                //var_dump($contentsRequest);
                return $response;
            }
        );
    };
});

Используя Жадность 6.2.

Я тоже боролся с этим в течение последних нескольких дней, пытаясь создать метод аудита HTTP-взаимодействий с различными API. В моем случае решение состояло в том, чтобы просто перемотать тело запроса.

тело запроса фактически реализовано как поток. Поэтому, когда запрос отправляется, Guzzle читает из потока. Чтение полного потока перемещает внутренний указатель потока в конец. Так когда ты ... звоните getContents() после выполнения запроса внутренний указатель уже находится в конце потока и ничего не возвращает.

решение? Перемотайте указатель на начало и прочитайте поток еще раз.

<?php
// ...
$body = $request->getBody();
echo $body->getContents(); // -->nothing

// Rewind the stream
$body->rewind();
echo $body->getContents(); // -->The request body :)

вы можете воспроизвести строку данных, созданную запросом, выполнив

$data = array(
    "key" => "value",
    "key2" => "value",
); 

$response = $client->request('POST', 'itemupdate', [
    'auth' => [$username, $password],
    'json' => $data,
]);

// ...

echo json_encode($data);

это выведет ваши данные в виде строки JSON.

документация на http://php.net/manual/fr/function.json-encode.php

редактировать

жрать есть Request и Response класса (и многие другие).
Request фактически с getQuery() метод, который возвращает объект, содержащий код data как частный, такой же, как и все другие члены.
Также вы не можете получить к нему доступ.

вот почему я думаю, что ручное кодирование-это более простое решение. Если вы хотите знать, что делается с помощью Guzzle, у него также есть Collection класс, который преобразует данные и отправляет их в запросе.