web-dev-qa-db-fra.com

Comment puis-je obtenir le corps des données SENT avec Guzzle PHP?

J'utilise Guzzle (v6.1.1) dans PHP pour faire une demande POST à un serveur. Cela fonctionne très bien. J'ajoute quelques fonctions de journalisation pour me connecter ce qui a été envoyé et reçu et je ne sais pas comment obtenir les données envoyées par Guzzle au serveur. Je peux obtenir la réponse très bien, mais comment puis-je obtenir les données envoyées? serait la chaîne JSON.)

Voici la partie pertinente de mon code:

$client = new GuzzleHttp\Client(['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

Toute aide serait appréciée. J'ai essayé de chercher dans Guzzle sourcecode une fonction similaire à getBody () qui fonctionnerait avec la demande, mais je ne suis pas un expert en PHP donc je n'ai rien trouvé d'utile) J'ai également beaucoup cherché sur Google, mais je n'ai trouvé que des gens qui parlaient de récupérer la réponse du serveur, ce avec quoi je n'ai aucun problème.

18
ruhnet

Vous pouvez faire ce travail en créant un Middleware .

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",
    ]
]);

Ceci, cependant, est déclenché avant de recevoir la réponse. Vous voudrez peut-être faire quelque chose comme ceci:

$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;
            }
        );
    };
});
18
Federkun

Utilisation de Guzzle 6.2.

J'ai également eu du mal avec ces derniers jours, tout en essayant de créer une méthode pour auditer les interactions HTTP avec différentes API. La solution dans mon cas était simplement de rembobiner le corps de la demande.

Le corps de la requête est en fait implémenté sous la forme d'un flux . Ainsi, lorsque la demande est envoyée, Guzzle lit dans le flux. La lecture du flux complet déplace le pointeur interne du flux vers la fin. Ainsi, lorsque vous appelez getContents() une fois la demande effectuée, le pointeur interne se trouve déjà à la fin du flux et ne renvoie rien.

La solution? Rembobinez le pointeur au début et relisez le flux.

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

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

Vous pouvez reproduire la chaîne de données créée par la demande en faisant

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

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

// ...

echo json_encode($data);

Cela produira vos données sous forme de chaîne JSON.

Documentation sur http://php.net/manual/fr/function.json-encode.php

[~ # ~] modifier [~ # ~]

Guzzle a une classe Request et Response (et bien d'autres).
Request a effectivement une méthode getQuery() qui renvoie un objet contenant votre data comme privé, comme tous les autres membres.
Vous ne pouvez pas non plus y accéder.

C'est pourquoi je pense que le codage manuel est la solution la plus simple. Si vous voulez savoir ce qui est fait par Guzzle, il a aussi une classe Collection qui transforme les données et les envoie en requête.

1
chalasr