Matthijs Wessels
Matthijs Wessels

Reputation: 6739

param0 disappearing in Soap request in PHP using SoapClient class

I am trying to call a web service from PHP code using SoapClient.

$service = new SoapClient($wsdl);
$service->myFunction('something', 'anotherthing', 'onemore');

If I turn on trace and get the last request, I can see that the first parameter is always missing from the Soap message, i.e. param0 is never there. It's the same in functions with less or more parameters.

The Soap request:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Body>
    <myFunction />
    <param1>anotherthing</param1>
    <param2>onemore</param2>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

What I expect it to be (and what my web service accepts when using soapUI):

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Body>
    <myFunction>
      <param0>something</param0>
      <param1>anotherthing</param1>
      <param2>onemore</param2>
    </myFunction>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

It's the same with

__soapCall('myFunction', array($something, $anotherthing, $onemore));

I am using xampplite on Windows XP.

Update: http://programming.itags.org/php/236781/ is a link to someone with the same problem (posted in 2008 with no answers :( ).

Update 2: I also noticed that it doesn't put the xml elements representing the parameters as child elements of the element representing the function. This can't be right?!!?

I've done a horrible fix where I overload the __doRequest function and edit the $request variable. It works, but it sucks. I might as well compile the entire request myself......

Update 3: To me it feels like PHP is just malfunctioning. But if it was a bug in the soap implementation, I'd think there would be more info on it on the web. aaaargh. Next attempt is to try NuSoap and PEAR.

Update 4: To round it off, I didn't try NuSoap and PEAR. I just went with my 'hack' because it worked and there were other activities that needed doing. Furthermore, the demo has been given and for the next phase PHP will not be used anymore. So the whole thing will be re-implemented anyway.

Upvotes: 2

Views: 3101

Answers (2)

KingJackaL
KingJackaL

Reputation: 780

TL;DR version: you're calling your SOAP method incorrectly. Put the parameters in an array, rather than having them as separate arguments for PHP's __call().

I had this same problem, and it was really stumping me. I guessed I just bashed my head against the wall a bit longer though. I found I was doing:

$soapclient = new SoapClient($uri);
$soapclient->MethodName($param0, $param1, $param2);

Which curiously, creates SOAP XML like so:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<MethodName/>
<param1>$param1</param1>
<param2>$param2</param2>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

What I should have done was called the method like so:

$soapclient = new SoapClient($uri);
$soapclient->MethodName(array($param0, $param1, $param2));

This creates SOAP XML like so:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<MethodName>
<param0>$param0</param0>
<param1>$param1</param1>
<param2>$param2</param2>
</MethodName>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

In hindsight, kinda obvious - but I can see how I mistook the SOAP parameters for also being the PHP parameters!

Upvotes: 2

Peter Kruithof
Peter Kruithof

Reputation: 10764

You can see what the SoapClient is sending by extending the doRequest method and debugging the $request argument.

Alternatively, SoapClient::__getLastRequest can also be used, but I had some problems in the past when my calls generated an exception (ie: do not comply with the WDSL), in doRequest you can inspect the XML prior to sending.

Be assured that passing along arguments works like expected, and that your problem probably lies with the actual variables you are sending, or that the call doesn't match the operation as specified in the WSDL.

Upvotes: 0

Related Questions