Posted by: phillipnb | April 25, 2011

PHP and Web Services – Part 3


In the last edition of our survey about “PHP and Web Services”, we saw how to perform a web service using HTTP POST. In this edition we will continue reinforcing our knowledge about webservices but this time we will use PHP with SOAP to demonstrate our web services.

As usual we will have a server to serve the requests to the web service and a client to use the public methods exposed by the server of the web service. To create SOAP client and server using PHP, we need to enable the SOAP extension provided by the php class library. To enable this extension, open your php.ini config file and change ;extension = php_soap.dll to extension=php_soap.dll. If this extension is not present in the php.ini file (provided you are using the latest version of php of atleast 5.x), just add this extension and restart the web server.

In this type of web service where we are using SOAP, the web service is defined using a wsdl (web service description language document) file, a xml document in the http://schemas.xmlsoap.org/wsdl namespace. The entities involved in the web service interact using SOAP messages which are transferred using HTTP. The wsdl document specifies what methods are available for that particular web service. Basically the wsdl tells the client what functions/methods are exposed by the server of that particular web services which can be consumed by the client.

In this edition we will be creating a client and server to provide book catalog service. The client will use the exposed method which takes id of the book as an input parameter and returns the name, author and other details of the requested book. The method provided by the server and method that clients can use is mentioned in a file called the wsdl document.

Let us explore more into the structure of this wsdl document. The wsdl document used in this web service consist of the following elements – types, message, portType, binding and service. Of these types, message and portType fall in the group called abstract definitions while binding and service fall into the group called concrete descriptions. You can read more about abstract and concrete descriptions here. At the root of the wsdl file is the ‘definition’ element which includes the namespace definitions. After this, the ‘type’ element can be seen which contains the datatype definitions. While the ‘message’ element describes the data being exchanged between the server and client, the ‘portType’ element describes a set of supported operations. The ‘binding’ element describes the supported protocol and the ‘service’ element describes a collection of ports. Here is an example of the wsdl file called bookcatalog. Wsdl that we are using in this example:

<?xml version = '1.0' encoding = 'UTF-8' ?> 
<definitions name='BookCatalog' 
	  targetNamespace = 'http://localhostws/BookCatalog' 
	  xmlns:tns       = 'http://localhostws/BookCatalog ' 
	  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='getBookCatalogRequest'> 
	  <part name='BookCatalogId' type='xsd:string'/> 
	</message> 

	<message name='getBookCatalogResponse'> 
	  <part name='Result' type='xsd:string'/> 
	</message> 

	<portType name='BookCatalogPortType'> 
	  <operation name='getBookCatalogEntry'> 
	    <input message='tns:getBookCatalogRequest'/> 
	    <output message='tns:getBookCatalogResponse'/> 
	  </operation> 
	</portType> 

	<binding name='BookCatalogBinding' type='tns:BookCatalogPortType'> 
	  <soap:binding style='rpc' 
	    transport='http://schemas.xmlsoap.org/soap/http'/> 
	  <operation name='getBookCatalogEntry'> 
	    <soap:operation soapAction='urn:localhostws-BookCatalog#getBookCatalogEntry'/> 
	    <input> 
	      <soap:body use='encoded' namespace='urn:localhostws-BookCatalog' 
		encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> 
	    </input> 
	    <output> 
	      <soap:body use='encoded' namespace='urn:localhostws-BookCatalog' 
		encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> 
	    </output> 
	  </operation> 
	</binding> 

	<service name='BookCatalogService'> 
	  <port name='BookCatalogPort' binding='tns:BookCatalogBinding'> 
	    <soap:address location='http://localhostws/soap-server.php'/> 
	  </port> 
	</service>
</definitions>

Now, let us discuss how to create our SOAP client and SOAP server. We will be able to understand the bookcatalog.wsdl better once we have the code for the server and client ready.

The SOAP Server
Please take a look at the definition and methods that the SOAP class has to offer using the url http://www.php.net/manual/en/class.soapclient.php. The functions that a soap server provides can be accessed at http://www.php.net/manual/en/class.soapserver.php. Using the SOAP class, let us write our client and server. Our server will load a wsdl file which has the name of the function that the server is offering. In our case, the server will be offering a function called ‘getBookCatalogEntry’.

Here is what php code for our server will look like:

ini_set("soap.wsdl_cache_enabled", "0"); // Sets the value of a configuration option, to prevent wsdl cache
$server = new SoapServer("bookcatalog.wsdl"); // create a new instance of the soap server
$server-&gt;addFunction("getBookCatalogEntry"); // Adds one or more functions to handle SOAP requests
$server-&gt;handle(); // handle the soap request

// custom function to handle the book catalog request
function getBookCatalogEntry($BookCatalogId) {

    $myBook = '';

    switch($BookCatalogId) {

        case 'BookCatalog1';
			$myBook = getMyBook('BookCatalog1');
			break;

        case 'BookCatalog2';
			$myBook = getMyBook('BookCatalog2');
			break;

        default;
            $myBook = 'error in catalogue request';
            break;
    }

    return $myBook;
} //

// custom function to format the output
function getMyBook($bookId) {
    if ($bookId == 'BookCatalog1') {
        return '<table><tr><th>Book Name</th><th>Author</th><th>Publisher</th><th>ISBN</th></tr><tr><td>PHP and MySQL Web Development</td><td>Luke Welling, Laura Thomson</td><td>Addison-Wesley</td><td>9780672329166</td></tr></table>';
    }
    else if ($bookId == 'BookCatalog2') {
        return '<table><tr><th>Book Name</th><th>Author</th><th>Publisher</th><th>ISBN</th></tr><tr><td>PHP Objects, Patterns and Practice</td><td>Matt Zandstra</td><td>Apress</td><td>143022925X</td></table>';
    }
    else {
        return 'Book not available';
    }
} //

Dissecting the soap server code – the first lines tells php to disable any wsdl caching. The second line loads whatever wsdl file is requested by passing the name of the wsdl file to SOAP Server Class constructor. The third line exposes whatever function the server is ready to cater and finally the line ‘server->handle()’ handles the request from the client.

We are done with the server, here is code for the soap client:

  $client    = new SoapClient("bookcatalog.wsdl"); // create an instance of the soap client class in the wsdl mode, pass uri of wsdl file
  $catalogId = 'BookCatalog1'; // the id of the book whose information we would like the server to pass to us
  $response  = $client-&gt;getBookCatalogEntry($catalogId); // call the advertised webservice method
  echo $response; // display what we received from the soap server

Dissecting the client code – the first line instantiates the soap client and loads the wsdl file. Using the client object we will call the appropriate method exposed in the wsdl file. The response returned by the server will be displayed back to the user who used the client to get the response.

If all is well (if there are no coding errors), then we will get a response when we execute the client code. Here is the output of our webservice

<table><tr><th>Book Name</th><th>Author</th><th>Publisher</th><th>ISBN</th></tr><tr><td>PHP and MySQL Web Development</td><td>Luke Welling, Laura Thomson</td><td>Addison-Wesley</td><td>9780672329166</td></tr></table>

So, this is how we create a soap server, soap client and wsdl to consume a web service. Hope you enjoyed this as much as I did – as usual I am waiting for your comments and suggestions. Those folks who would like to know more about php web services can take a look at this url. In the next edition of this series, we will explore how to use web services using xml rpc.

So, till next time – Happy PHPing

About these ads

Responses

  1. I like the straight forward explanation but get this error myself.

    Fatal error: Uncaught SoapFault exception: [VersionMismatch] Wrong Version in newsoapclient.php:15 Stack trace: #0 : SoapClient->__soapCall(‘getBookCatalogE…’, Array) #

  2. Now I get the error

    Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn’t load from ‘http://myurl/bookcatalog.wsdl

    any ideas

  3. this can happen due to several reasons. You need to check why your wsdl couldn’t be loaded from that url. The reasons could be – Is the url correct, is the file name correct, do you have permission to access that file, etc etc etc

  4. I love php and mysql web development and its helped me improve my customer support in many ways. Its an easy yet very powerful tool. I started my search and found what i needed about how and what Web Based Support Desk Software was all about.. PHP and Web Services Part 3 My Experience with PHP was easy to learn with and the best thing about it is that I can access my support tickets wherever I go through my iphone. – Fred


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: