Error trying to perform Soap request with Soapclient

Asked

Viewed 724 times

0

I’m having trouble making requests to a webservice using the Soapclient (PHP library). This is the message returned: SOAP-ERROR: Encoding: Object has in the 'Client' Property. Any idea what it might be? Below is the code used.

Php class:

/**
 * Classe de interação com interface soap
 * 
 * @package     crphp
 * @subpackage  webservice
 * @author      Fábio J L Ferreira <[email protected]>
 * @license     MIT (consulte o arquivo license disponibilizado com este pacote)
 * @copyright   (c) 2016, Fábio J L Ferreira
 */

namespace Crphp\Webservice;

use \Exception;
use \SoapClient;
use \DOMDocument;

class Soap
{
    /**
     * Armazena uma instância de SoapClient
     *
     * @var string 
     */
    private $client;

    /**
     * Consulta o WSDL informado
     * 
     * @param   string       $wsdl
     * @param   array        $opcoes
     * @return  null|string  null = sucesso, string = erro
     */
    public function setWsdl($wsdl, array $opcoes = null)
    {
        if (!$opcoes) {
            $opcoes = [
                'cache_wsdl' => 'WSDL_CACHE_NONE',
                'soap_version' => 'SOAP_1_2',
                'trace' => 1,
                'encoding' => 'UTF-8'
            ];
        }

        try {
            $this->client = new SoapClient($wsdl, $opcoes);
        } catch (Exception $e) {
            return $e->getMessage();
        }
    }

    /**
     * Dispara a consulta contra o serviço informado
     * 
     * @param   string       $acao
     * @param   array        $argumentos
     * @return  null|string  null = sucesso, string = erro
     */
    public function consult($acao, array $argumentos = null)
    {
        try {
            if(!$this->client) {
                throw new Exception("Ocorreu um erro ao tentar chamar o serviço <b>{$acao}</b>.");
            }

            $this->client->__soapCall($acao, array($argumentos));
        } catch (Exception $e) {
            return $e->getMessage();
        }
    }

    /**
     * Retorna os métodos expostos pelo WSDL
     * 
     * @return array|null
     */
    public function getMethods()
    {
        if($this->client) {
            foreach($this->client->__getFunctions() as $metodo) {  
                $array = explode(' ', substr($metodo, 0, strpos($metodo, '(')));
                $metodos[] = end($array);
            }
            return $metodos;
        }
    }

    /**
     * Retorna o XML enviado
     * 
     * @return string|void em caso de sucesso retorna string, para erro retorna null
     */
    public function getRequest()
    {
        return ($this->client) ? $this->client->__getLastRequest() : null;
    }

    /**
     * Retorna o XML recebido
     * 
     * @return string|void em caso de sucesso retorna string, para erro retorna null
     */
    public function getResponse()
    {
        return ($this->client) ? $this->client->__getLastResponse() : null;
    }

    /**
     * Converte string para o formato XML
     * 
     * @param string $soap
     * @return null|string se não tiver dado para transformação retorna null
     */
    public function formatXML($soap)
    {
        if(!$soap) {
            return null;
        }

        $dom = new DOMDocument;
        $dom->preserveWhiteSpace = false;
        $dom->formatOutput = true;
        $dom->loadXML($soap);

        return htmlentities($dom->saveXML());
    }
}

php test.

<?php

require_once('../vendor/autoload.php');

use Crphp\Webservice\Soap;

$args = [
    'ConsultarEnderecoRequest' => [
        'Cliente' => [
            'sistema' => 'xpto',
        ],
        'numDDD'   => 'xx',
        'numTerminal'   => 'xxxxxxxx',
    ]
];

$obj = new Soap;
if($erro = $obj->setWsdl('http://...?wsdl')) {
    exit($erro);
}

// Retorna os métodos expostos pelo WSDL
// $obj->getMethods();

// Se o retorno for null então significa que a consulta não foi realizada
if(!$erro = $obj->consult('Consultar', $args)) {
    // Perfumaria
    echo '<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>';
    echo "<pre class='prettyprint' >" . $obj->formatXML($obj->getResponse()) . "</pre>";
} else {
    echo $erro;
}

In a very simple and summarized way, the xml sent should be something like:

<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <ConsultarRequest>
   <Cliente>
    <sistema>XPTO</sistema>
   </Cliente>
   <numDDD>xx</numDDD>
   <numTerminal>xxxxxxxx</numTerminal>
  </ConsultarRequest>
 </soapenv:Body>
</soapenv:Envelope>

1 answer

0

I identified the cause of the error. After analyzing the code more calmly I arrived at the method Consult (namespace: Crphp Webservice Soap), precisely in this excerpt:

$this->client->__soapCall($acao, array($argumentos));

When I create an instance of this class I am already passing an array as parameter, so it makes no sense to use:

$this->client->__soapCall($acao, array($argumentos));

but yes:

$this->client->__soapCall($acao, $argumentos);

I had not noticed this error previously because in an XML without child elements the problem is not noticed.

Commit correction: https://github.com/crphp/webservice/commit/7d8f19d7d404613570daf3dc2c7c9f1c55e8a509

Browser other questions tagged

You are not signed in. Login or sign up in order to post.