Last week I got an assignment to make a service for transferring a huge chunk of data. It sounded OK till i found out, that the end-user wants to use SOAP calls. I’ve never deal with SOAP so didn’t have much to work with. Couple of days went by, hours and hours of searching the web for a solution, number of Tweets, etc. But right on the point where i would gave up, i found a solution to all the problems.
SOAP is easy to use, if you use it with a simple application and in a simple way. But oh boy, it can get complicated. If you’re not a PHP expert or an advanced developer i suggest using REST (POST) calls or XML-RPC .. trust me, you’ll thank me.
First, you have to understand the way that SOAP works. It’s not just a data transfer protocol, it can do magic too :) It includes two sides – server and client. Server accepts the call, process it and (if needed) returns a response. In other hand, client makes the call and accepts the response.
The most important part of SOAP call is the WSDL (Web Services Description Language) file in which you describe how the transfer works, which data can be “pushed” and which data can be returned. The PHP part isn’t as complicated for a newbie as the writing of the WSDL file.
WSDL file can be divided in small chunks in which every chunk represents the important part of final call / response. I’ll just post an example and explain, what and how things work ..
<?xml version =’1.0′ encoding =’UTF-8′ ?>
<definitions
targetNamespace=’server.php’
xmlns:tns=’server.php’
xmlns:wsdl=’http://schemas.xmlsoap.org/wsdl/’
xmlns:soap=’http://schemas.xmlsoap.org/wsdl/soap/’
xmlns=’http://schemas.xmlsoap.org/wsdl/’>
<message name=’incomeMessage’>
<part name=’string’ type=’xsd:string’/>
</message>
<message name=’outcomeMessage’>
<part name=’string’ type=’xsd:string’/>
</message>
<portType name=’updatePortType’>
<operation name=’callMe’>
<input message=’tns:incomeMessage’/>
<output message=’tns:outcomeMessage’/>
</operation>
</portType>
<binding name=’updateBinding’ type=’tns:updatePortType’>
<soap:binding style=’rpc’ transport=’http://schemas.xmlsoap.org/soap/http’/>
<operation name=’callMe’>
<soap:operation soapAction=’urn:server.php’/>
<input>
<soap:body use=’encoded’
namespace=’urn:server.php’
encodingStyle=’http://schemas.xmlsoap.org/soap/encoding/’/>
</input>
<output>
<soap:body use=’encoded’
namespace=’urn:http://yourdomain.comserver.php’
encodingStyle=’http://schemas.xmlsoap.org/soap/encoding/’/>
</output>
</operation>
</binding>
<service name=’updateService’>
<port name=’updatePort’ binding=’updateBinding’>
<soap:address location=’http://yourdomain.com/rest’/>
</port>
</service>
</definitions>
I hope the code didn’t scared you, cuz it’s quite simple to understand. All the code must be written between “<definitions></definitions>” tags, as the WSDL 1.0, WSDL 1.1 and WSDL 1.2 formats are the only one which currently works with PHP (with WSDL 2.0 you can skip “definitions” tags but it won’t work with PHP).
Then we have four objects – message, portType, binding and service.
message is a very important part as you define the data that the service accepts and returns. It must contain a “name” tag and at least one “part” object. With “<part ../>” you define the number and type of chunks in the call, that will be transferred. I suggest writing two “message” objects, one for the “input” (received) and one for the “output” (returned) data.
portType combines the two messages defined and the name of operation (function) that will be called, when the call is made.
binding is the part in WSDL in which you define the port, which should be used and type and URL of input (received) and output (returned) data.
service – it just sticks all the previous definitions together and makes the call and response possible.
Now, i know i didn’t define every tag very specifically, because i don’t feel the need to. Please visit “the site”, where you can find all the explanations that will help you write a perfect WSDL file – w3.org/TR/wsdl.
We have a WSDL file, let’s say we store it as updateMe.wsdl. Now let’s build some webservice, shall we? At first, we need to build a SOAP Server part. I used the SOAP class that is included in PHP5=>, you may use NuSOAP library instead – it’s is very popular (and works with PHP4), but you’ll have to make some adjustments to the PHP code.
The “server” component needs to contain only 2 lines of code, we’ll use 3:
$server = new SoapServer('updateMe.wsdl');
$server->setClass("updateClass");
$server->handle();
So we’ve made a new SoapServer, set a class and “executed” the service. That simple? No. You need a class within a function to handle the received data and return a response. And here it is ..
class updateClass
{
function callMe($input)
{
return "I cannot belive my eyes, it is so simple.";
}
}
What we’ve done here is we’ve set up a class within which the call can execute a function. And where did we define the function, which will be used in the call? In WSDL file. We defined it in the “portType/operation” and later on in the “binding/operation”. We received the data as a string ‘$input’ and returned the response (returned data) to the client.
So, let’s say we’ve saved the “server component” as server.php. We have a updateMe.wsdl and server.php in a root directory, so we only have to write a Client to “push” data to the server.
Here is an example of a Client that should work with the server / WSDL file written above ..
$client = new SoapClient('updateMe.wsdl');
$xml = $client->__soapCall("callMe", array('string' => 'We have landed.'));
Simple, ain’t it? Only 2 lines of code. So, what did we do here? We’ve made a call to updateMe.wsdl file, which made a call to server.php file, and passed a chunk of data via string variable to the function called callMe. The function is held in the updateClass, which we defined in the server component ($server->setClass(“updateClass”)) ..
So .. how does SOAP works? It’s not a traditional “POST/GET” request call. The call is made over the WSDL file and can’t be made directly to server component itself. If you add more operations / messages to the WSDL file, you can transfer more chunks of data to the server. It works like this ..
Client -> WSDL -> Server -> Client
I hope this “how-to” helps you deal with SOAP & PHP. SOAP is not used as much as it could be, while the developer has to learn an additional programming language (WSDL). In some ways it’s as simple as a REST request, which is being used very often .. but for more complex data transfers and with clients that don’t all have “advanced developers” I wouldn’t suggest using it for a client-end service but it’s a nice was to transfer data from one server to another.