Guzzlehttp - Bagaimana mendapatkan tanggapan dari Guzzle 6?

163

Saya mencoba menulis pembungkus di sekitar api yang sedang dikembangkan perusahaan saya. Ini tenang, dan menggunakan tukang pos saya dapat mengirim permintaan posting ke titik akhir seperti http://subdomain.dev.myapi.com/api/v1/auth/dengan nama pengguna dan kata sandi sebagai data POST dan saya diberikan kembali token. Semua berfungsi seperti yang diharapkan. Sekarang, ketika saya mencoba dan melakukan hal yang sama dari PHP saya mendapatkan kembali sebuah GuzzleHttp\Psr7\Responseobjek, tetapi sepertinya tidak dapat menemukan token di mana pun di dalamnya seperti yang saya lakukan dengan permintaan tukang pos.

Kode yang relevan terlihat seperti:

$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...

Output dari kode di atas terlihat seperti (peringatan, dinding teks):

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) {
    }
  }
}

Output dari Postman kira-kira seperti:

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

Jelas saya kehilangan sesuatu tentang bekerja dengan objek respons di Guzzle. Respons Guzzle menunjukkan 200 status kode pada permintaan, jadi saya tidak yakin apa yang harus saya lakukan untuk mengambil data yang dikembalikan.

Greg
sumber
33
$response->getBody()->getContents()tidak bekerja?
Federkun

Jawaban:

435

Guzzle mengimplementasikan PSR-7 . Itu berarti bahwa secara default akan menyimpan isi pesan dalam Stream yang menggunakan aliran temp PHP. Untuk mengambil semua data, Anda dapat menggunakan operator casting:

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

Anda juga bisa melakukannya dengan

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

Perbedaan antara kedua pendekatan adalah bahwa getContentsmengembalikan konten yang tersisa, sehingga panggilan kedua tidak menghasilkan apa-apa kecuali Anda mencari posisi aliran dengan rewindatau 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

Sebagai gantinya, menggunakan operasi string casting PHP, ia akan membaca semua data dari aliran dari awal sampai akhir tercapai.

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

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

Federkun
sumber
5
Fungsi getContents hanya di satu bagian kecil dari dokumentasi Guzzle 6 (di bagian stream), dan saya melewatkannya. Anda menyelamatkan saya dari banyak pencarian.
Maximus
58
TERIMA KASIH. Sulit dipercaya bahwa ini tidak lebih jelas dalam dokumentasi. Bahkan dokumentasi resmi mereka ( docs.guzzlephp.org/en/latest ) membuatnya seperti memanggil $ res-> getBody () mengembalikan apa yang biasanya Anda harapkan.
John
24
Mereka harus benar-benar meletakkan sesuatu seperti catatan atau pemberitahuan di dokumen resmi. Saya menghabiskan dua hari untuk masalah ini.
cwhsu
+1 Dokumentasi Guzzle secara salah menyatakannya "you can pass true to this method [getBody()] to retrieve the body as a string.". Tampaknya itu tidak berfungsi untuk saya menggunakan Guzzle 6, tetapi casting ke string atau menggunakan getContents () tidak berfungsi.
Magnus W
8
Anda juga dapat menggunakan json_decode. Misalnya bungkus tanggapan Anda dengan json_decode($response, true);ini akan mengembalikan array.
Sygon
13

Jika mengharapkan JSON kembali, cara paling sederhana untuk mendapatkannya:

$data = json_decode($response->getBody()); // returns an object

// OR

$data = json_decode($response->getBody(), true); // returns an array

json_decode()akan secara otomatis melemparkan tubuh ke string, sehingga tidak perlu menelepon getContents().

Maksim Ivanov
sumber
1
Mengapa jawaban ini tidak mendapat perhatian lebih ??? Inilah tepatnya yang saya butuhkan. Terima kasih @MaskimIvanov
Eric McWinNEr
Itu juga hal yang paling sederhana dan mudah bagi saya. Terima kasih
Alator