2015-08-03 17 views
8

Chciałem użyć Guzzle 6, aby pobrać odpowiedź xml ze zdalnego interfejsu API. To jest mój kod:Pobierz całą treść odpowiedzi XML za pomocą klienta HTTP 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 $body zwróci GuzzleHttp\Psr7\Stream obiektu:

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

mogłem wtedy zadzwonić $body->read(1024) czytać 1024 bajtów z odpowiedzi (co czytać w XML).

Chciałbym jednak pobrać całą odpowiedź XML z mojego żądania, ponieważ będę musiał przetworzyć ją później przy użyciu rozszerzenia SimpleXML.

Jak najlepiej pobrać odpowiedź XML z obiektu GuzzleHttp\Psr7\Stream, aby można ją było wykorzystać do analizowania?

Czy linia while będzie w pętli?

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

Doceniam twoją radę.

Odpowiedz

9

W GuzzleHttp\Psr7\Stream implemtents umowie Psr\Http\Message\StreamInterface który ma następujące zaoferować Państwu:

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

Oddanie obiektu do łańcucha wywoła stanowiącego podstawę __toString() metodę, która jest częścią interfejsu. method name __toString() is special in PHP.

Jako realizacji w GuzzleHttp „brakowało” w celu zapewnienia dostępu do rzeczywistego uchwyt strumienia, więc nie można skorzystać z funkcji strumienia PHP, która pozwala na bardziej (strumień-jak) operacji „strumień wysadzanej” w pewnych okolicznościach, takich jak stream_copy_to_stream, stream_get_contents lub file_put_contents. To może nie być oczywiste od pierwszego wejrzenia.

+0

Dziękuję sir! Nie myślałem o rzuceniu całego ciała odpowiedzi na ciąg. – luqo33

+0

Mam do czynienia z tym samym problemem. Czy mógłbyś rozwinąć swoją odpowiedź z krok po kroku? Jak wyglądałby teraz cały kod? – davejal

3

zrobiłem to w ten sposób:

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()); 
} 

Moja aplikacja zwraca zawartość w ciągu znaków XML przygotowanej zawartości i chlać żądanie wysyła nagłówki z akceptować param application/xml.

+0

Używam laravel i otrzymałem komunikat o błędzie, że nie znaleziono klasy "SimpleXMLElement". Czy masz łatwą naprawę? – davejal

+0

Użyj phpinfo(), aby uzyskać informacje, jeśli rozszerzenie SimpleXML jest włączone lub wyłączone w twoim PHP. Jeśli używasz PHP nowszego niż 5.1.2, rozszerzenie SimpleXML powinno być domyślnie włączone. – Toni

+0

Tak, jest włączona, a moja wersja to 5.5.11. Jakieś inne kontrole, które mogłem zrobić? – 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;