PHP Advent Calendar Day 18

18 Dec 2007

Today's entry, provided by Christian Wenz, is entitled WSDL Despite PHP 5.

Christian Wenz

Name
Christian Wenz
Blog
hauser-wenz.de/blog/
Biography
Christian Wenz got hooked on PHP when he introduced it to one of the largest web sites back in early '99, and he hasn't looked back since.
Location
Munich, Germany

We are working a lot with web services these days. One of the things I like best, from a technical perspective, is the WSDL standard. WSDL is used to provide information about a SOAP web service: operation, data types, messages, location, and the like. Using WSDL, consuming a web service is very easy. Most technologies support an implementation of the proxy pattern and can automatically create a local proxy object from a WSDL description. Here's a quick example that shows how PHP 5's very own SOAP extension works with WSDL:

  1. <?php
  2.  
  3. $c = new SoapClient('/path/to/wsdl');
  4. $result = $c->myWebServiceMethod($arg1, $arg2);
  5.  
  6. ?>

Calling myWebServiceMethod() on the local client object instructs the SOAP extension to call the remote method of the same name and parse the SOAP data coming back from the service. Unfortunately, the SOAP extension does not support automatic WSDL creation for a SOAP service, whereas most competing technologies do. One of the beauties of PHP is that the language is not strongly typed, which makes WSDL generation more difficult. However, there are several ways to generate WSDL with PHP 5, with a little help.

Userland Code

One of the oldest web services libraries for PHP is NuSOAP. The original site has not been updated in over three years, but NuSOAP remains in active development on SourceForge. When creating a NuSOAP service, call the configureWSDL() method, and provide the data types for input arguments and the return value when calling register(). Here's a short example (sans the actual business logic of the service, which resides in myWebServiceMethod()):

  1. <?php
  2.  
  3. function myWebServiceFunction($inputValue) {
  4.     /* ... */
  5. }
  6.  
  7. require 'nusoap.php';
  8.  
  9. $soap = new soap_server();
  10. $soap->configureWSDL('NuSOAPService', 'http://hauser-wenz.de/');
  11. $server->wsdl->schemaTargetNamespace = 'http://soapinterop.org/xsd/';
  12.  
  13. $soap->register('myWebServiceMethod',
  14.                 array('inputValue' => 'xsd:string'),
  15.                 array('outputValue' => 'xsd:string'),
  16.                 'http://soapinterop.org/');
  17.  
  18. $HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
  19. $soap->service($HTTP_RAW_POST_DATA);
  20.  
  21. ?>

NuSOAP runs on PHP 4 and PHP 5. A NuSOAP-based web service is obviously compatible with SOAP extension and other SOAP implementations as well.

Extensions

A binary PHP extension performs much better than userland code. An extension that supports WSDL generation is WSF/PHP from WSO2. Once you install, XML comments provide hints to the extension about the data types and operations used in the service.

  1. <?php
  2.  
  3. function myWebServiceFunction($inputValue) {
  4.     /* ... */
  5. }
  6.  
  7. $ops = array('myWebServiceFunction' => 'myWebServiceFunction');
  8. $svr = new WSService(array('operations' => $ops, 'bindingStyle' => 'rpc-enc'));
  9. $svr->reply();
  10.  
  11. ?>

When you request this page, you get basic information about the service. When you append ?wsdl to the address, you get a fitting WSDL description.

Additional Options

Some other tools and packages promise WSDL generation; here is a (possibly incomplete) list:

Even if you don't want to rely on external code or extensions, using one of the aforementioned options might still be of interest. You can use them to create the WSDL, and then use that WSDL (after modifying the service's address) to fuel the SOAP extension-based service.

Happy holidays!