2015-05-30 20 views
82

Sto provando a scrivere un wrapper attorno a un'ape che la mia azienda sta sviluppando. È riposante e, utilizzando Postman, posso inviare una richiesta di posta a un endpoint come http://subdomain.dev.myapi.com/api/v1/auth/ con un nome utente e una password come dati POST e mi viene restituito un token. Tutto funziona come previsto. Ora, quando provo a fare lo stesso da PHP, ottengo un oggetto GuzzleHttp\Psr7\Response, ma non riesco a trovare il token da nessuna parte al suo interno come ho fatto con la richiesta Postman.Guzzlehttp - Come ottenere il corpo di una risposta da Guzzle 6?

Il codice in questione si presenta come:

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

L'uscita del codice di cui sopra sembra qualcosa di simile (avvertimento, parete in entrata di testo):

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

L'uscita dal postino era qualcosa di simile:

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

Chiaramente mi manca qualcosa sul lavoro con gli oggetti risposta in Gu zzle. La risposta di Guzzle indica un codice di stato di 200 sulla richiesta, quindi non sono esattamente quello che devo fare per recuperare i dati restituiti.

+19

'$ response-> getBody() -> getContents()' non funziona? – Federkun

+3

Sei un genio geniale @Leggendario. Sei una leggenda nel tuo tempo libero. Non so come non ho trovato 'getContents()' prima. – Greg

risposta

241

Attrezzi per guaina PSR-7. Ciò significa che per impostazione predefinita memorizzerà il corpo di un messaggio in un Stream che utilizza i flussi di tempo PHP. Per recuperare tutti i dati, è possibile utilizzare operatore di casting:

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

Si può anche farlo con

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

La differenza tra i due approcci è che getContents restituisce i restanti contenuti, in modo che un secondo la chiamata non restituisce nulla a meno che non si cerchi la posizione dello stream con rewind o 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 

Invece, usings operazioni stringa di fusione di PHP, si legge tutti i dati dal flusso dall'inizio fino al raggiungimento della finale.

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

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

+4

La funzione getContents è solo in una piccola parte della documentazione di Guzzle 6 (nella sezione stream) e l'ho persa. Mi hai salvato da un sacco di ricerche. – Maximus

+26

GRAZIE. È incredibile che questo non sia più chiaro nella documentazione. Anche la loro documentazione ufficiale (http://docs.guzzlephp.org/en/latest/) fa sembrare che chiamare $ res-> getBody() restituisca ciò che normalmente ti aspetteresti. – John

+9

Dovrebbero davvero mettere qualcosa come una nota o un avviso nei documenti ufficiali. Ho perso due giorni su questo problema. – cwhsu