3

I want to check the xml based responses from server, here is an example of the response format.

<response>
    <code>success</code>
</response>

My existing code,

use GuzzleHttp\Client;

$client = new Client();
$response = $client->post('http://example.com/verify', [
    'form_params' => [
        'transID' => 1234,
        'orderID' => 6789,
        'token' => '0X45FJH79GD3332'
    ]
]);

$xml = $response->xml();

dd($xml);

However, when I make request to the server error occurs like below.

Call to undefined method GuzzleHttp\Psr7\Response::xml()

Dipendra Gurung
  • 5,720
  • 11
  • 39
  • 62

1 Answers1

3

I believe the documentation is outdated (for version 5.3 actually, I suppose you're using 6.*)

They say Sending a request will return a Guzzle\Http\Message\Response object. In this version of Guzzle, you're getting GuzzleHttp\Psr7\Response instead which does not implement xml() method.

You can go and check old version at https://github.com/guzzle/guzzle/blob/5.3/src/Message/Response.php and use that method. Eg. create this:

public function xml(Request $request, array $config = [])
{
    $disableEntities = libxml_disable_entity_loader(true);
    $internalErrors = libxml_use_internal_errors(true);
    try {
        // Allow XML to be retrieved even if there is no response body
        $xml = new \SimpleXMLElement(
            (string) $request->getBody() ?: '<root />',
            isset($config['libxml_options']) ? $config['libxml_options'] : LIBXML_NONET,
            false,
            isset($config['ns']) ? $config['ns'] : '',
            isset($config['ns_is_prefix']) ? $config['ns_is_prefix'] : false
        );
        libxml_disable_entity_loader($disableEntities);
        libxml_use_internal_errors($internalErrors);
    } catch (\Exception $e) {
        libxml_disable_entity_loader($disableEntities);
        libxml_use_internal_errors($internalErrors);
        throw new YourXmlParseException(
            'Unable to parse response body into XML: ' . $e->getMessage(),
            $request,
            $e,
            (libxml_get_last_error()) ?: null
        );
    }
    return $xml;
}
simPod
  • 11,498
  • 17
  • 86
  • 139
  • Hi there. I have the same problem. I get an XML response from guzzle and should be able to access the valus inside that SimpleXML object. Now that guzzle 6 does not support that I tried to use the function from the old version. But I don't know how to actually use it. I would have to extend Guzzle? Or how can I get a proper XML object out of it? @Dipendra Gurung (https://stackoverflow.com/users/1516665/dipendra-gurung), how did you get it to work? – Merc Mar 25 '20 at 10:02
  • damn, I was not able to mention you, dipendra gurung, properly. Normally it should autosuggest whenever I type @dipe.... right? – Merc Mar 25 '20 at 10:05
  • 1
    @Merc I have slightly modified my answer. Just use this function within your code and pass Response. (did not test it, it's just modified fcn from 5.3 code) – simPod Mar 25 '20 at 14:09
  • 2
    I found another solution, which is maybe not as robust as this, but does the trick: `$body = $response->getBody(); $xml = simplexml_load_string($body);` ‍♂️ – Merc Mar 26 '20 at 16:01