Получите весь текст ответа XML с помощью HTTP-клиента Guzzle 6

Я хотел использовать Guzzle 6 для получения ответа xml от удаленного API. Это мой код:

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

Вардампинг $body вернет объект GuzzleHttp\Psr7\Stream:

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

Затем я мог бы вызвать $body->read(1024), чтобы прочитать 1024 байта из ответа (который будет читаться в формате xml).

Однако я хотел бы получить весь ответ XML из моего запроса, так как мне нужно будет проанализировать его позже, используя расширение SimpleXML.

Как лучше всего получить XML-ответ от объекта GuzzleHttp\Psr7\Stream, чтобы его можно было использовать для синтаксического анализа?

Подойдет ли while петля?

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

Я был бы признателен за ваш совет.


person luqo33    schedule 03.08.2015    source источник


Ответы (2)


GuzzleHttp\Psr7\Stream реализует контракт Psr \Http\Message\StreamInterface, который предлагает вам следующее:

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

Приведение объекта к строке вызовет базовый метод __toString(), который является частью интерфейса. имя метода __toString() является особенным в PHP.

Поскольку реализация в GuzzleHttp «упустила» доступ к фактическому дескриптору потока, вы не можете использовать потоковые функции PHP, которые допускают более «потоковые» (подобные потоку ) операции в определенных обстоятельствах, например stream_copy_to_stream, stream_get_contents или file_put_contents. Это может быть неочевидно на первый взгляд.

person hakre    schedule 03.08.2015
comment
Спасибо, сэр! Не думал о преобразовании всего тела ответа в строку. - person luqo33; 04.08.2015
comment
Я столкнулся с той же проблемой. Не могли бы вы уточнить свой ответ с пошаговым исправлением? Как теперь будет выглядеть полный код? - person davejal; 19.07.2016

Я сделал это так:

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

Мое приложение возвращает содержимое в виде строки с подготовленным XML-содержимым, а запрос Guzzle отправляет заголовки с параметром accept application/xml.

person Toni    schedule 25.02.2016
comment
Я использую laravel и получил ошибку, что класс SimpleXMLElement не найден. У вас есть легкое решение? - person davejal; 19.07.2016
comment
Используйте phpinfo(), чтобы получить информацию о том, включено или отключено расширение SimpleXML в вашем PHP. Если вы используете PHP новее 5.1.2, расширение SimpleXML должно быть включено по умолчанию. - person Toni; 19.07.2016
comment
да, он включен, и моя версия 5.5.11. Любые другие проверки, которые я мог бы сделать? - person davejal; 19.07.2016
comment
Не могли бы вы предоставить нам немного кода, где это произошло? - person Toni; 21.07.2016
comment
Должен ли я задать новый вопрос? - person davejal; 28.07.2016
comment
Попробуйте поставить '\' перед вызовом SimpleXMLElement, например new \SimpleXMLElement(... - person DJ Far; 29.07.2016
comment
спасибо, но это не помогло, вылезла вот такая ошибка: String could not be parsed as XML - person davejal; 30.07.2016