Actual result:
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://localhost/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <ns1:PerformTransactionArgumentsResponse> <return xsi:type="SOAP-ENC:Struct"> <errorMsg xsi:type="xsd:string">Ok</errorMsg> <status xsi:type="xsd:string">0</status> <timeStamp xsi:type="xsd:string">2011-04-26T19:13:55.421875+05:00</timeStamp> </return> </ns1:PerformTransactionArgumentsResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
Expected result without <return xsi:type="SOAP-ENC:Struct"></return>
tag.
I am doing it first time, and actually I know almost nothing about Soap Server, could you tell me, how can I remove return tag ?
this is the code on server side:
class PerformTransactionArgumentsResponse { public $errorMsg = "Ok"; public $status = "0"; public $timeStamp = "2011-04-26T19:13:55.421875+05:00"; } class MyAPI { function PerformTransactionArguments() { return new PerformTransactionArgumentsResponse; } } $options=array('uri'=>'localhost/'); $server = new SoapServer(NULL,$options); $server->setClass('MyAPI'); $server->handle();
Advertisement
Answer
In order to do what you want you must make a WSDL document and pass it both to the server and the client. Let’s start creating a WSDL document named wsdl-pruebas.wsdl
with the following content:
<?xml version="1.0" encoding="UTF-8"?> <definitions name="TransactionArguments" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://localhost/pruebas" targetNamespace="http://localhost/pruebas"> <types> <xs:schema targetNamespace="http://localhost/pruebas"> <xs:element name="PerformTransactionArgumentsResponse"> <xs:complexType> <xs:sequence> <xs:element name="errorMsg" type="xs:string"/> <xs:element name="status" type="xs:string"/> <xs:element name="timeStamp" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> </types> <message name="PerformTransactionArgumentsRequest"/> <message name="PerformTransactionArgumentsResponse"> <part name="return" element="ns1:PerformTransactionArgumentsResponse"/> </message> <portType name="PerformTransactionArgumentsPortType"> <operation name="PerformTransactionArguments"> <input message="PerformTransactionArgumentsRequest"/> <output message="PerformTransactionArgumentsResponse"/> </operation> </portType> <binding name="PerformTransactionArgumentsBinding" type="PerformTransactionArgumentsPortType"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="PerformTransactionArguments"> <soap:operation soapAction=""/> <input/> <output> <soap:body use="encoded" namespace="http://localhost/pruebas" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </output> </operation> </binding> <service name="PerformTransactionArgumentsResponseService"> <documentation>Returns an error message.</documentation> <port name="PerformTransactionArgumentsPort" binding="PerformTransactionArgumentsBinding"> <soap:address location="http://localhost/pruebas/soap-server.php"/> </port> </service> </definitions>
The definition seems overwhelming, but it’s quite simple once you analize it section by section, which we’ll analize below. First we define the type for the response here:
<types> <xs:schema targetNamespace="http://localhost/pruebas"> <xs:element name="PerformTransactionArgumentsResponse"> <xs:complexType> <xs:sequence> <xs:element name="errorMsg" type="xs:string"/> <xs:element name="status" type="xs:string"/> <xs:element name="timeStamp" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> </types>
As you can see it’s identical to your class. We’ll use it later. Next we define the request and response messages:
<message name="PerformTransactionArgumentsRequest"/> <message name="PerformTransactionArgumentsResponse"> <part name="return" element="ns1:PerformTransactionArgumentsResponse"/> </message>
We’re defining an empty request, but a response of the type of your class. Take note of the name
attribute, which values return
. This is what you currently see in the response of the server. Next we define the “interface” for the operations of your SOAP server:
<portType name="PerformTransactionArgumentsPortType"> <operation name="PerformTransactionArguments"> <input message="PerformTransactionArgumentsRequest"/> <output message="PerformTransactionArgumentsResponse"/> </operation> </portType>
input
and output
simply point to the messages described above. Next we define the “details” of the portType:
<binding name="PerformTransactionArgumentsBinding" type="PerformTransactionArgumentsPortType"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="PerformTransactionArguments"> <soap:operation soapAction=""/> <input/> <output> <soap:body use="encoded" namespace="http://localhost/pruebas" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </output> </operation> </binding>
Here soap:binding tells us it’s using SOAP 1.1.
Finally we expose the binding through the service section:
<service name="PerformTransactionArgumentsResponseService"> <documentation>Returns an error message.</documentation> <port name="PerformTransactionArgumentsPort" binding="PerformTransactionArgumentsBinding"> <soap:address location="http://localhost/pruebas/soap-server.php"/> </port> </service>
The soap:address point to the URL of your soap server script (in this example, http://localhost/pruebas/soap-server.php
).
After defining the WSDL document, we code the soap server script (in this example will be named soap-server.php
):
class PerformTransactionArgumentsResponse { public $errorMsg = "Ok"; public $status = "0"; public $timeStamp = "2011-04-26T19:13:55.421875+05:00"; } class MyAPI { function PerformTransactionArguments() { return new PerformTransactionArgumentsResponse; } } $options = [ 'soap_version' => SOAP_1_1, 'cache_wsdl' => WSDL_CACHE_NONE ]; $server = new SoapServer('http://localhost/pruebas/soap-pruebas.wsdl', $options); $server->setClass('MyAPI'); $server->handle();
This time we provide the URL of our WSDL document and modify the $options
array.
To see all this in action we create a SOAP client script (in this example will be soap-client.php
):
try { $options = [ 'soap_version' => SOAP_1_1, 'trace'=>1 ]; $client = new SOAPClient('http://localhost/pruebas/soap-pruebas.wsdl', $options); $response = $client->PerformTransactionArguments(); header('Content-type:text/xml'); echo $client->__getLastResponse(); } catch (SoapFault $e) { echo $e; }
Again, we specify the URL of our WSDL document. Running the client script will give this:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns1="http://localhost/pruebas" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <ns1:PerformTransactionArgumentsResponse xsi:type="ns1:PerformTransactionArgumentsResponse"> <errorMsg xsi:type="xsd:string">Ok</errorMsg> <status xsi:type="xsd:string">0</status> <timeStamp xsi:type="xsd:string">2011-04-26T19:13:55.421875+05:00</timeStamp> </ns1:PerformTransactionArgumentsResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
What differs from the generated response of your soap server script?
In the soap:binding definition, if we modify the value of the style
sttribute to from document
to rpc
:
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
We’ll get this response:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://localhost/pruebas" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <ns1:PerformTransactionArgumentsResponse> <return xsi:type="ns1:PerformTransactionArgumentsResponse"> <errorMsg xsi:type="xsd:string">Ok</errorMsg> <status xsi:type="xsd:string">0</status> <timeStamp xsi:type="xsd:string">2011-04-26T19:13:55.421875+05:00</timeStamp> </return> </ns1:PerformTransactionArgumentsResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
Which is the response you’re getting currently.
EDIT: Lastly, if we change the soap:body line:
<soap:body use="encoded" namespace="http://localhost/pruebas" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
to this:
<soap:body use="literal"/>
The response will be:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://localhost/pruebas"> <SOAP-ENV:Body> <ns1:PerformTransactionArgumentsResponse> <errorMsg>Ok</errorMsg> <status>0</status> <timeStamp>2011-04-26T19:13:55.421875+05:00</timeStamp> </ns1:PerformTransactionArgumentsResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
NOTE: For this I’m assuming the scripts and the WDSL are located in http://localhost/pruebas/
.