Darshan
Darshan

Reputation: 59

Building SOAP body with native php client

I am creating an soap client with php, I have successfully added the header and invoked the service.

my problem is my api responded with

Application error has occurred, please review your request and try again.

I used the

htmlentities($client->__getLastRequest())

to compare with the outgoing XML and expected xml, then I found following

outgoing

<SOAP-ENV:Body>
<ns1:ping/>
</SOAP-ENV:Body>

expected

<S:Body>
    <ns3:ping xmlns:ns2="http://www.example.com/example" xmlns:ns3="http://example.core.engine.tflip.uua.com/">
        <arg0>
            <ns2:token>Wed Apr 06 01:19:24 IST 2016</ns2:token>
        </arg0>
    </ns3:ping>
</S:Body>

it is clear I am sending a null body, but I don't know how to create these because I am using

$params = array(
          "token" => 'Wed Apr 06 01:19:24 IST 2016'
        );
$result = $client->__soapCall("ping", array($params));

to call the service, I need to create the above structure and also have to add those namespaces for those nodes.

Also please suggest me whether it will cause any problems in defining instead of

Please help me on this.

Upvotes: 1

Views: 1713

Answers (2)

Darshan
Darshan

Reputation: 59

Finally found a solution which works for me at-least just posting if anyone in need.

With all the security headers, I created the soap client and included the class which accepts the username and the password. and It turned out that the wsdl it self handled the name space for the ping method.

so my code goes like this.

craeted the soap client with the wsdl and made it traceable so that i can use the htmlentities($client->__getLastRequest()); and htmlentities($client->__getLastResponse()); to check my request and response xml. Note the htmlentities() has been used to make it visible in the browser.

$client = new SoapClient("--the wsdl link--", array('trace' => 1));

Also setting the soap header with the class WsseAuthHeader where I am initiating all the authentication and the headers required for the service. WsseAuthHeader class extends the SoapHeader.

$client->__setSoapHeaders(Array(new WsseAuthHeader("username", "password")));

With the created $client invoking the ping method (operation) in service with the expected values.

$response = $client->ping(array('arg0'=>array('token'=>'test','timestamp'=>(new DateTime())->format('Y.m.d H:i:s'))));

finally can do the echo to test the output with the

echo htmlentities($client->__getLastResponse());

Hope this helps, and special thanks for @Marcel for his support.

Upvotes: 1

Marcel
Marcel

Reputation: 5119

The PHP SoapClient is a bit confusing sometimes. The easiest way is to work with objects. The following example is untestet.

class Ping {
    protected $arg0;

    public function setArg(SoapVar $oArg0) {
        $this->arg0 = $oArg;
    }

    public function encode() {
        return new SoapVar(
            $this,
            SOAP_ENC_OBJECT,
            null,
            null,
            'ping',
            'http://example.core.engine.tflip.uua.com/'
        }
    }
}

class Arg {
    protected $token;

    public function getToken() {
        return $this->token;
    }

    public function setToken($oToken) {
        if (!($oToken instanceof SoapVar)) {
            $oToken = new SoapVar(
                $oToken,
                XSD_STRING,
                null,
                null,
                'token',
                'http://www.example.com/example'
            );
        }

        $this->token = $oToken;
    }

    public function encode() {
        return new SoapVar(
            $this, 
            SOAP_ENC_OBJECT, 
            null,
            null,
            'arg0'
        );
    }
}

try {
    // init your soap client with wsdl
    $oClient = new SoapClient(...);

    // init your arg object
    $oArg = new Arg();
    $oArg->setToken('Wed Apr 06 01:19:24 IST 2016');
    $oArgEncoded = $oArg->encode();

    // init the ping object
    $oPing = new Ping();
    $oPing->setArg($oArgEncoded);
    $oPingEncoded = $oPing->encode();

    // call the ping method with soap encoded arg object
    $oResult = $oClient->ping($oPingEncoded);
} catch (SoapFault $oSoapFault) {
    echo "<pre>";
    var_dump($oSoapFault);
    echo "</pre>";
}

First of all we have our arg object with the token member and getters and setters. The encode function gives the arg object as a SoapVar object fully encoded. So you can call the ping method of the websercive directly with the soap client.

Upvotes: 3

Related Questions