Tuesday, September 23, 2008

PHP SOAP Extension

PHP SOAP Extension is one of the most popular PHP implementations of SOAP 1.1 and 1.2, developed by The PHP Group. SOAP is a lightweight protocol for exchange of information in a decentralized, distributed environment. , So SOAP is the most popular web services format. It's a SIMPLE way to allow programs written in different languages running on different computers to communicate and share data. SOAP is a W3C standard for passing messages across the network and calling functions on remote computers.

SOAP, formerly known as Simple Object Access Protocol (until the acronym was dropped in version 1.2), came around shortly after XML-RPC was released. It was created by a group of developers with backing from Microsoft. Interestingly, the creator of XML-RPC, David Winer, was also one of the primary contributors to SOAP. Winer released XML-RPC before SOAP, when it became apparent to him that though SOAP was still a way away from being completed, there was an immediate need for some sort of web service protocol.

PHP 5's SOAP extension is the first attempt to implement the SOAP protocol for PHP in C. SOAP is included in the PHP 5.0.4 package for Windows distributed by Zend Technologies. It has some advantages over the existing implementations written in PHP itself, the main one being speed. The extension is currently marked as experimental, but should gradually become more stable and reliable as time progresses.

SOAP is an XML based protocol that consists of four parts: an envelope that defines a framework for describing what is in a message and how to process it, a set of encoding rules for expressing instances of application-defined data types, a convention for representing remote procedure calls and responses and a binding convention for exchanging messages using an underlying protocol. SOAP can potentially be used in combination with a variety of other protocols; however, the only bindings defined in this document describe how to use SOAP in combination with HTTP and the experimental HTTP Extension Framework. XML SOAP uses XML for transmitting data.

To show you an example of how PHP SOAP Extension can be used in a SOAP client application, here is my first SOAP PHP program, soapClient.php

Example : soapClient.php



<?php
$client = new SoapClient("http://[insert real path here]/productOrder.wsdl");

print_r($client->serverFunction('UserName', password', $Integer1, $string1));
?>


This client function will communicate with productOrder.wsdl file on the server. WSDL (Web Services Definition Language) is an XML based standard designed to describes protocol bindings and message formats of Web services. WSDL is often pronounced as "Whiz-Dull.

Being XML-based, this allows clients to automatically discover everything about the functionality of the web service. Human-readable documentation is technically not required for a SOAP service that uses a WSDL document, though it is still highly recommended. Let's take a look at the structure of a WSDL document and how we can use it to figure out what is available to us in a SOAP-based web service. Out of all three specifications that we're going to look at in relationship to SOAP, WSDL is the most ethereal. Both supporters and detractors often call writing WSDL documents a black art.

The only argument against using it is that the client has to load the relevant WSDL document from the server before the RPC can be made, and this can take a significant amount of time in a Web environment. In order to speed things up, PHP's ext/soap uses a WSDL caching feature that can be controlled through setting the soap.wsdl_cache_enabled, soap.wsdl_cache_dir and soap.wsdl_cache_ttl configuration directives, either in your php.ini or by using ini_set()(see SOAP Server Example ). By default, WSDL caching is turned on and caches WSDL files for one day.





Beginning with a root definitions element, WSDL documents follow this basic structure:


<definitions>
<types>

</types>
<message>

</message>
<portType>

</portType>
<binding>

</binding>
</definitions>

As you can see, in addition to the definitions element, there are four main sections to a WSDL document: types, message, portType, and binding.

Here is a copy of the WSDL document for the demonstration Web service used in in the SOAP Server.
Example : productOrder.wsdl



<?xml version ='1.0' encoding ='UTF-8' ?>
<definitions name=SOAPDefn
xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'
xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
xmlns='http://schemas.xmlsoap.org/wsdl/'>

<message name='getOrderRequest'>
<part name='userID' type='xsd:string'/> //passing variable 1
<part name='paswrd' type='xsd:string'/> //passing variable 2
<part name='orderNo' type='xsd:integer'/> //passing variable 3
<part name='itemName' type='xsd:string'/> //passing variable 4

</message>
<message name='getOrderResponse'>
<part name='Result' type='xsd:integer'/>
</message>

<portType name='orderPortType'>
<operation name='saveOrderDetails'>
<input message='tns:getOrderRequest'/>
<output message='tns:getOrderResponse'/>
</operation>
</portType>

<binding name='orderBinding' type='tns:orderPortType'>
<soap:binding style='rpc'
transport='http://schemas.xmlsoap.org/soap/http'/>
<operation name='saveOrderDetails'>
<soap:operation soapAction='urn:xmethods-delayed-quotes#saveOrderDetails'/>
<input>
<soap:body use='encoded' namespace='urn:xmethods-delayed-quotes'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</input>
<output>
<soap:body use='encoded' namespace='urn:xmethods-delayed-quotes'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</output>
</operation>
</binding>

<service name='orderService'>
<port name='StockQuotePort' binding='tns:orderBinding'>
<soap:address location= ‘http://[insert real path here]/ server.php'/>
</port>
</service>
</definitions>

Note: The WSDL caching feature is on by default. During the development of your WSDL file it should be turned off.



Now it's time to create our server.

Example : server.php


<?php
require_once "SOAPFunctionsManager.obj";
ini_set("soap.wsdl_cache_enabled", "0"); //disabling WSDL cache
$server = new SoapServer("productOrder.wsdl");
$server->setClass("SOAPFunctionsManager");
$server->handle();
?>


$server->setClass method connect the SoapServer object with the SOAPFunctionsManager class, and used all methods in the SOAPFunctionsManager class with the SOAP Server .

Example: SOAPFunctionsManager

class SOAPFunctionsManager
{
function saveOrderDetails($userName, $paswrd, $orderNo, $itemname) {
if($this->authenticateUser($userName, $paswrd)) {
$order_Index = $this->saveOrder($orderNo, $itemname);
return $order_Index;
} else {
return 0;
}
}

function saveOrder($orderNo, $itemname)
{
execute MY SQL Query here..
return last Insert_ID()

}

function authenticateUser($userName, $paswrd) {
if($userName == '_USER_NAME_' && $paswrd == '_PASSWORD_)
return 1;
else
return 0;
}

}

Conclusion

In this article, we were introduced to SOAP, the most complex of the web service protocols so far. SOAP relies heavily on other standards like WSDL and XSD. Well XML-RPC is a great way to transmit simple data as shown in the above sample. However, SOAP allows Objects to be used. These days most people are working in object oriented languages and know the power of using Objects. SOAP allows you to harness that power in your web applications.

The SOAP extension is fully documented at http://www.php.net/manual/en/ref.soap.php.
If you read the SOAP Extension reference page, you will see that SOAP Extension support SOAP client applications with a class called SoapClient, which offers the following functions:

• SoapClient->__construct() - constructs a new SoapClient object
• SoapClient->__soapCall() - Calls a SOAP function
• SoapClient->__getFunctions() - Returns list of SOAP functions
• SoapClient->__getLastRequestHeaders() - Returns last SOAP request headers
• SoapClient->__getLastRequest() - Returns last SOAP request
• SoapClient->__getLastResponseHeaders() - Returns last SOAP response headers
• SoapClient->__getLastResponse() - Returns last SOAP response
• ...

The extension is still in the early development phase, so your feedback will help to make it more stable, reliable, usable and fast. Please report any problems you find at http://bugs.php.net/.

References
http://devzone.zend.com/node/view/id/689