web-dev-qa-db-fra.com

Guzzlehttp - Comment obtenir le corps d'une réponse de Guzzle 6?

J'essaie d'écrire un wrapper autour d'une API que mon entreprise est en train de développer. C'est reposant et avec Postman, je peux envoyer une demande de publication à un ordinateur d'extrémité tel que http://subdomain.dev.myapi.com/api/v1/auth/ avec un nom d'utilisateur et un mot de passe comme POST données. Un jeton est alors restitué. Tout fonctionne comme prévu. Maintenant, lorsque j'essaie de faire de même avec PHP, je récupère un objet GuzzleHttp\Psr7\Response, mais je n'arrive pas à trouver le jeton à l'intérieur, contrairement à ce que j'ai fait avec la requête Postman.

Le code correspondant ressemble à ceci:

$client = new Client(['base_uri' => 'http://companysub.dev.myapi.com/']);
$response = $client->post('api/v1/auth/', [
    'form_params' => [
        'username' => $user,
        'password' => $password
    ]
]);

var_dump($response); //or $resonse->getBody(), etc...

La sortie du code ci-dessus ressemble à quelque chose comme (avertissement, mur de texte entrant):

object(guzzlehttp\psr7\response)#36 (6) {
  ["reasonphrase":"guzzlehttp\psr7\response":private]=>
  string(2) "ok"
  ["statuscode":"guzzlehttp\psr7\response":private]=>
  int(200)
  ["headers":"guzzlehttp\psr7\response":private]=>
  array(9) {
    ["connection"]=>
    array(1) {
      [0]=>
      string(10) "keep-alive"
    }
    ["server"]=>
    array(1) {
      [0]=>
      string(15) "gunicorn/19.3.0"
    }
    ["date"]=>
    array(1) {
      [0]=>
      string(29) "sat, 30 may 2015 17:22:41 gmt"
    }
    ["transfer-encoding"]=>
    array(1) {
      [0]=>
      string(7) "chunked"
    }
    ["content-type"]=>
    array(1) {
      [0]=>
      string(16) "application/json"
    }
    ["allow"]=>
    array(1) {
      [0]=>
      string(13) "post, options"
    }
    ["x-frame-options"]=>
    array(1) {
      [0]=>
      string(10) "sameorigin"
    }
    ["vary"]=>
    array(1) {
      [0]=>
      string(12) "cookie, Host"
    }
    ["via"]=>
    array(1) {
      [0]=>
      string(9) "1.1 vegur"
    }
  }
  ["headerlines":"guzzlehttp\psr7\response":private]=>
  array(9) {
    ["connection"]=>
    array(1) {
      [0]=>
      string(10) "keep-alive"
    }
    ["server"]=>
    array(1) {
      [0]=>
      string(15) "gunicorn/19.3.0"
    }
    ["date"]=>
    array(1) {
      [0]=>
      string(29) "sat, 30 may 2015 17:22:41 gmt"
    }
    ["transfer-encoding"]=>
    array(1) {
      [0]=>
      string(7) "chunked"
    }
    ["content-type"]=>
    array(1) {
      [0]=>
      string(16) "application/json"
    }
    ["allow"]=>
    array(1) {
      [0]=>
      string(13) "post, options"
    }
    ["x-frame-options"]=>
    array(1) {
      [0]=>
      string(10) "sameorigin"
    }
    ["vary"]=>
    array(1) {
      [0]=>
      string(12) "cookie, Host"
    }
    ["via"]=>
    array(1) {
      [0]=>
      string(9) "1.1 vegur"
    }
  }
  ["protocol":"guzzlehttp\psr7\response":private]=>
  string(3) "1.1"
  ["stream":"guzzlehttp\psr7\response":private]=>
  object(guzzlehttp\psr7\stream)#27 (7) {
    ["stream":"guzzlehttp\psr7\stream":private]=>
    resource(40) of type (stream)
    ["size":"guzzlehttp\psr7\stream":private]=>
    null
    ["seekable":"guzzlehttp\psr7\stream":private]=>
    bool(true)
    ["readable":"guzzlehttp\psr7\stream":private]=>
    bool(true)
    ["writable":"guzzlehttp\psr7\stream":private]=>
    bool(true)
    ["uri":"guzzlehttp\psr7\stream":private]=>
    string(10) "php://temp"
    ["custommetadata":"guzzlehttp\psr7\stream":private]=>
    array(0) {
    }
  }
}

La sortie de Postman était quelque chose comme:

{
    "data" : {
        "token" "fasdfasf-asfasdfasdf-sfasfasf"
    }
}

Clairement, il me manque quelque chose sur le travail avec les objets de réponse dans Guzzle. La réponse Guzzle indique un code de statut 200 sur la demande. Je ne sais donc pas exactement ce que je dois faire pour récupérer les données renvoyées.

130
Greg

Guzzle implements PSR-7 . Cela signifie que par défaut, le corps du message sera stocké dans un Stream utilisant les flux PHP temp. Pour récupérer toutes les données, vous pouvez utiliser l'opérateur de casting:

$contents = (string) $response->getBody();

Vous pouvez aussi le faire avec

$contents = $response->getBody()->getContents();

La différence entre les deux approches est que getContents renvoie le contenu restant, de sorte qu'un deuxième appel ne renvoie rien sauf si vous recherchez la position du flux avec rewind ou seek.

$stream = $response->getBody();
$contents = $stream->getContents(); // returns all the contents
$contents = $stream->getContents(); // empty string
$stream->rewind(); // Seek to the beginning
$contents = $stream->getContents(); // returns all the contents

Au lieu de cela, en utilisant les opérations de conversion de chaînes de caractères de PHP, il lit toutes les données du flux depuis le début jusqu'à la fin.

$contents = (string) $response->getBody(); // returns all the contents
$contents = (string) $response->getBody(); // returns all the contents

Documentation: http://docs.guzzlephp.org/en/latest/psr7.html#responses

363
Federkun