I'm trying to consume a webservice using PHP.
This is the code I have:
<?php
ini_set('soap.wsdl_cache_enabled', false);
class SayHelloResponse
{
public $sayHelloResult;
public $greeting;
}
$client = new SoapClient(
'http://localhost:8000/greetings_server.php?wsdl', [
'trace' => 1,
'soap_version' => SOAP_1_2,
'classmap' => [
'sayHelloResponse' => SayHelloResponse::class,
]
]);
if ($argc === 1) {
echo "Service description:" . PHP_EOL;
echo "--------------------" . PHP_EOL;
echo "Functions:" . PHP_EOL;
print_r($client->__getFunctions());
echo "=====" . PHP_EOL;
echo "Types:" . PHP_EOL;
print_r($client->__getTypes());
} elseif ($argv[1] == "h") {
try {
echo "Making the call" . PHP_EOL;
$sayHelloResponse = $client->sayHello(
[
'name' => $argv[2]
]);
var_dump($sayHelloResponse);
var_dump($client->__getLastResponse());
} catch (SoapFault $exception) {
echo "Error: " . $exception->getMessage() . PHP_EOL;
var_dump($client->__getLastRequest());
var_dump($client->__getLastResponse());
}
} else {
echo $client->sayGoodBye($argv[2]);
}
When I run the script without any CLI arguments I get:
Service description:
--------------------
Functions:
Array
(
[0] => sayHelloResponse sayHello(sayHello $parameters)
[1] => sayGoodByeResponse sayGoodBye(sayGoodBye $parameters)
)
=====
Types:
Array
(
[0] => struct sayHello {
string name;
}
[1] => struct sayHelloResponse {
string sayHelloResult;
}
[2] => struct sayGoodBye {
string name;
}
[3] => struct sayGoodByeResponse {
string sayGoodByeResult;
}
)
Then, when I run it with php greetings.php h Mauro
I get:
Making the call
object(SayHelloResponse)#2 (2) {
["sayHelloResult"]=>
NULL
["greeting"]=>
NULL
}
string(559) "<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="urn:Greetings" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:enc="http://www.w3.org/2003/05/soap-encoding"><env:Body xmlns:rpc="http://www.w3.org/2003/05/soap-rpc"><ns1:sayHelloResponse env:encodingStyle="http://www.w3.org/2003/05/soap-encoding"><rpc:result>greeting</rpc:result><greeting xsi:type="xsd:string">Hello Mauro!</greeting></ns1:sayHelloResponse></env:Body></env:Envelope>
"
So I can see the result I'm looking for is right there (Hello Mauro!
), I just don't know how to access it :(
The thing is, if I try to use the webservice in non-wsdl mode it works fine but I need to use the WSDL (Which I'm generating at the other end with another PHP script).
And, if you're wondering, the WSDL seems to be fine as I checked it with SoapUI.
Thanks for your help
--
Edit:
I tried this little python script:
from zeep import Client
client = Client('http://localhost:8000/greetings_server.php?wsdl')
result = client.GreetingsService.sayHello('Mauro')
And when I run it I get:
Traceback (most recent call last):
File "/home/mauro/.local/lib/python3.8/site-packages/zeep/xsd/types/complex.py", line 206, in parse_xmlelement
result = element.parse_xmlelements(
File "/home/mauro/.local/lib/python3.8/site-packages/zeep/xsd/elements/indicators.py", line 617, in parse_xmlelements
item_subresult = element.parse_xmlelements(
File "/home/mauro/.local/lib/python3.8/site-packages/zeep/xsd/elements/element.py", line 206, in parse_xmlelements
raise UnexpectedElementError(
zeep.exceptions.UnexpectedElementError: Unexpected element 'greeting', expected 'sayHelloResult'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/mauro/.local/lib/python3.8/site-packages/zeep/proxy.py", line 46, in __call__
return self._proxy._binding.send(
File "/home/mauro/.local/lib/python3.8/site-packages/zeep/wsdl/bindings/soap.py", line 135, in send
return self.process_reply(client, operation_obj, response)
File "/home/mauro/.local/lib/python3.8/site-packages/zeep/wsdl/bindings/soap.py", line 231, in process_reply
result = operation.process_reply(doc)
File "/home/mauro/.local/lib/python3.8/site-packages/zeep/wsdl/bindings/soap.py", line 430, in process_reply
return self.output.deserialize(envelope)
File "/home/mauro/.local/lib/python3.8/site-packages/zeep/wsdl/messages/soap.py", line 101, in deserialize
body_result = self._deserialize_body(body)
File "/home/mauro/.local/lib/python3.8/site-packages/zeep/wsdl/messages/soap.py", line 442, in _deserialize_body
result = self.body.parse(xmlelement, self.wsdl.types, context=context)
File "/home/mauro/.local/lib/python3.8/site-packages/zeep/xsd/elements/element.py", line 126, in parse
return xsd_type.parse_xmlelement(
File "/home/mauro/.local/lib/python3.8/site-packages/zeep/xsd/types/complex.py", line 212, in parse_xmlelement
raise XMLParseError(exc.message)
zeep.exceptions.XMLParseError: Unexpected element 'greeting', expected 'sayHelloResult'
From this I get that there is a mismatch between the WSDL and the response the server is returning... I checked an older version of the greetings.wsdl file and found this misterious "greeting" element. I guess there must be a cache issue but I can't put my finger on it.
The python library I'm using is this
CodePudding user response:
I finally got my answer... It was a difficult one and I'm not even sure how I spotted it but the problem was in the WSDL definition.
More specifically, the binding style was wrong (or at least not compatible with the client I was using).
The original one was document
and I needed it to be rpc
.
Once I made that little change everything worked as expected.
I'm leaving a reference to my code for someone else looking at it.
Edit: for the record, this site's example was the one that tipped me off :)