2015-08-03 5 views
8

Volevo utilizzare Guzzle 6 per recuperare una risposta xml da un'API remota. Questo è il mio codice:Recupera l'intero corpo della risposta XML con il client HTTP di Guzzle 6

$client = new Client([ 
    'base_uri' => '<my-data-endpoint>', 
]); 
$response = $client->get('<URI>', [ 
    'query' => [ 
     'token' => '<my-token>', 
    ], 
    'headers' => [ 
     'Accept' => 'application/xml' 
    ] 
]); 
$body = $response->getBody(); 

Vardumping il $body sarebbe restituire un oggetto GuzzleHttp\Psr7\Stream:

object(GuzzleHttp\Psr7\Stream)[453] 
private 'stream' => resource(6, stream) 
... 
... 

ho potuto quindi chiamare $body->read(1024) a leggere 1024 byte dalla risposta (che avrebbe letto in XML).

Tuttavia, mi piacerebbe recuperare l'intera risposta XML dalla mia richiesta poiché sarà necessario analizzarla in seguito utilizzando l'estensione SimpleXML.

Come posso recuperare la risposta XML dall'oggetto GuzzleHttp\Psr7\Stream in modo che sia utilizzabile per l'analisi?

Il ciclo while vorrebbe andare?

while($body->read(1024)) { 
    ... 
} 

Apprezzerei il vostro consiglio.

risposta

9

I GuzzleHttp\Psr7\Stream implemtents contratto di Psr\Http\Message\StreamInterface che ha la seguente per offrire a voi:

/** @var $body GuzzleHttp\Psr7\Stream */ 
$contents = (string) $body; 

Casting l'oggetto a stringa chiamerà il metodo di __toString() sottostante, che è parte dell'interfaccia. Il method name __toString() is special in PHP.

Poiché l'attuazione entro GuzzleHttp "perso" per fornire l'accesso alla maniglia flusso attuale, quindi non è possibile fare uso di funzioni di flusso di PHP che permette di più (flusso-come) operazioni "snella" in circostanze, come stream_copy_to_stream, stream_get_contents o file_put_contents. Questo potrebbe non essere ovvio a prima vista.

+0

Grazie signore! Non ho pensato di trasmettere tutto il corpo della risposta alla stringa. – luqo33

+0

Sto affrontando lo stesso problema. Potresti elaborare la tua risposta, con una soluzione passo passo? Come sarebbe il codice completo ora? – davejal

3

ho fatto in questo modo:

public function execute ($url, $method, $headers) { 
    $client = new GuzzleHttpConnection(); 
    $response = $client->execute($url, $method, $headers); 

    return $this->parseResponse($response); 
} 

protected function parseResponse ($response) { 
    return new SimpleXMLElement($response->getBody()->getContents()); 
} 

La mia applicazione restituisce contenuti nella stringa con XML contenuti preparato, e gozzovigliare richiesta invia le intestazioni con accettare param application/xml.

+0

Sto usando laravel e ho ricevuto un errore nella classe 'SimpleXMLElement' non trovata. Hai una soluzione facile? – davejal

+0

Usa phpinfo() per ottenere informazioni se l'estensione SimpleXML è abilitata o disabilitata nel tuo PHP. Se stai utilizzando PHP più recente della versione 5.1.2, l'estensione SimpleXML dovrebbe essere abilitata per impostazione predefinita. – Toni

+0

sì, è abilitato e la mia versione è 5.5.11. Qualche altra verifica che potrei fare? – davejal

0
$client = new \GuzzleHttp\Client(); 
$response = $client->request('GET', $request_url, [ 
    'headers' => ['Accept' => 'application/xml'], 
    'timeout' => 120 
])->getBody()->getContents(); 

$responseXml = simplexml_load_string($response); 
if ($responseXml instanceof \SimpleXMLElement) 
{ 
    $key_value = (string)$responseXml->key_name; 
} 
0
$client = new \GuzzleHttp\Client(); 
$response = $client->request('GET', 'your URL'); 
$response = $response->getBody()->getContents(); 
return $response;