Ich versuche, einen Wrapper um eine API zu schreiben, die mein Unternehmen entwickelt. Es ist erholsam und mit Postman kann ich eine Post-Anfrage an einen Endpunkt senden, beispielsweise http://subdomain.dev.myapi.com/api/v1/auth/
mit einem Benutzernamen und einem Passwort als POST-Daten, und mir wird ein Token zurückgegeben. Alles funktioniert wie erwartet. Wenn ich jetzt versuche, dasselbe mit PHP zu tun, erhalte ich ein GuzzleHttp\Psr7\Response
Objekt zurück, kann aber das Token anscheinend nicht darin finden, wie ich es bei der Postman-Anfrage getan habe.
Der relevante Code sieht folgendermaßen aus:
$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...
Die Ausgabe des obigen Codes sieht ungefähr so aus (Warnung, eingehende Textwand):
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) {
}
}
}
Die Ausgabe von Postman war ungefähr so:
{
"data" : {
"token" "fasdfasf-asfasdfasdf-sfasfasf"
}
}
Offensichtlich fehlt mir etwas an der Arbeit mit den Antwortobjekten in Guzzle. Die Guzzle-Antwort zeigt einen 200-Statuscode in der Anforderung an, sodass ich nicht genau weiß, was ich tun muss, um die zurückgegebenen Daten abzurufen.
$response->getBody()->getContents()
funktioniert nicht?Antworten:
Guzzle implementiert PSR-7 . Das bedeutet, dass der Nachrichtentext standardmäßig in einem Stream gespeichert wird, der temporäre PHP-Streams verwendet. Um alle Daten abzurufen, können Sie den Casting-Operator verwenden:
$contents = (string) $response->getBody();
Sie können es auch mit tun
Der Unterschied zwischen den beiden Ansätzen besteht darin, dass
getContents
der verbleibende Inhalt zurückgegeben wird, sodass ein zweiter Aufruf nichts zurückgibt, es sei denn, Sie suchen die Position des Streams mitrewind
oderseek
.$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
Stattdessen werden unter Verwendung der String-Casting-Operationen von PHP alle Daten vom Anfang bis zum Ende aus dem Stream gelesen.
$contents = (string) $response->getBody(); // returns all the contents $contents = (string) $response->getBody(); // returns all the contents
Dokumentation: http://docs.guzzlephp.org/en/latest/psr7.html#responses
quelle
"you can pass true to this method [getBody()] to retrieve the body as a string."
. Das scheint für mich mit Guzzle 6 nicht zu funktionieren, aber das Casting in einen String oder mit getContents () funktioniert.json_decode($response, true);
diese Zeile einschließen, wird ein Array zurückgegeben.Wenn Sie JSON wieder erwarten, ist dies der einfachste Weg:
$data = json_decode($response->getBody()); // returns an object // OR $data = json_decode($response->getBody(), true); // returns an array
json_decode()
Wirft den Körper automatisch aufstring
, sodass kein Anruf erforderlich istgetContents()
.quelle
json_decode
impliziten Umwandeln des Antwortkörpers als Zeichenfolge. Trotzdem lohnt es sich, die akzeptierte Antwort zu verstehen, da es Probleme mit dem String Casting-Ansatz geben kann, bei dem nicht immer alle Daten abgerufen werden, wie im Kommentar von @Shardj hervorgehoben.So erhalten Sie eine Antwort im JSON-Format:
1.$response = (string) $res->getBody(); $response =json_decode($response); // Using this you can access any key like below $key_value = $response->key_name; //access key 2. $response = json_decode($res->getBody(),true); $key_value = $response['key_name'];//access key
quelle