Using Web Services in PHP


With all of this theory under your belt, it is time to sit down and actually connect to a Web Service and use one of the methods available to it.

Selecting a Web Service

For the purposes of this chapter, we will visit http://www.xmethods.com, which maintains a number of demonstration and sample services with which people can experiment. We will use the service called Currency Exchange Rate, which enables us to see the conversion rate between the national currencies of various nations.

On the web site, we can view the contents of the .wsdl file for this service, which is roughly as follows:

 <?xml version="1.0"?> <definitions name="CurrencyExchangeService"   targetNamespace="http://www.xmethods.net/sd/CurrencyExchangeService.wsdl"   xmlns:tns="http://www.xmethods.net/sd/CurrencyExchangeService.wsdl"   xmlns:xsd="http://www.w3.org/2001/XMLSchema"   xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"   xmlns="http://schemas.xmlsoap.org/wsdl/">   <message name="getRateRequest">     <part name="country1" type="xsd:string"/>     <part name="country2" type="xsd:string"/>   </message>   <message name="getRateResponse">     <part name="Result" type="xsd:float"/>   </message>   <portType name="CurrencyExchangePortType">     <operation name="getRate">       <input message="tns:getRateRequest" />       <output message="tns:getRateResponse" />     </operation>   </portType>   <binding name="CurrencyExchangeBinding"            type="tns:CurrencyExchangePortType">     <soap:binding style="rpc"        transport="http://schemas.xmlsoap.org/soap/http"/>     <operation name="getRate">       <soap:operation soapAction=""/>       <input >         <soap:body use="encoded"            namespace="urn:xmethods-CurrencyExchange"          encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>       </input>       <output >         <soap:body use="encoded"              namespace="urn:xmethods-CurrencyExchange"         encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>       </output>     </operation>   </binding>   <service name="CurrencyExchangeService">     <documentation>       Returns the exchange rate between the two       currencies     </documentation>     <port name="CurrencyExchangePort"           binding="tns:CurrencyExchangeBinding">       <soap:address         location="http://services.xmethods.net:80/soap"/>     </port>   </service> </definitions> 

The first thing we will look for is the portType element, to see what operations (methods) this service defines. We see that it has one, called getrate. If you go to the page for this Web Service on http://www.xmethods.net, you will see a link you can click called "View RPC Profile." If you click this, it will give you an eminently more understandable version of what the WSDL file says, as shown in Figure 27-2.

Figure 27-2. Viewing the RPC profile for a Web Service.


We know from this WSDL file that we want to connect to the Currency Exchange Rate Service operating at http://services.xmethods.net:80/soap and call the getrate method. This method accepts two parameters, which are the countries whose currencies are to be compared.

Configuring PHP

To access XML Web Services in PHP5 using SOAP, you need to do a little bit of extra configuration and setup work before you begin.

Unix Systems

To consume XML Web Services in PHP5 on Unix systems, you must make sure that PHP is configured and compiled with the --enable-soap switch. If not, none of the classes or functions will be available.

You can see whether the SOAP extension was included or verify its successful inclusion later by calling the phpinfo function and determining whether soap is listed as one of the modules.

Windows Systems

For users of the Microsoft Windows system, enabling SOAP support in PHP5 is as simple as adding the following line to your php.ini file:

 extension=php_soap.dll 

You can again verify its successful inclusion by calling the phpinfo function.

Configuration

There are three options in php.ini relevant to working with XML Web Services, all of which pertain to the handling of WSDL files.

  • soap.wsdl_cache_enabled (default: on) This tells PHP to cache WSDL files instead of getting them each time a connection to a service is made.

  • soap.wsdl_cache_dir (default: /tmp) This tells PHP where to cache .wsdl files it downloads. Note that the default location of /tmp likely will not work on most Windows machines.

  • soap.wsdl_cache_ttl (default 86400 (one day)) This indicates how long (in seconds) PHP will cache a file before fetching a new copy.

Our primary concern before using SOAP is to ensure that the value of the soap.wsdl_cache_dir contains a valid directory. We will check this in php.ini before continuing.

Working with the Service

After we have SOAP enabled and configured in PHP5, we can begin connecting to Web Services and invoking methods on them.

Using the SoapClient Class

The class with which we will most often work is the SoapClient class. It is extremely powerful and will hide a majority of the details of working with SOAP and WSDL, further making a compelling case for using XML Web Services.

The easiest way to create an instance of this class is to pass the constructor the URI of the WSDL file for the service, as follows:

 $client = new SoapClient(wsdl_uri); 

This constructor throws an exception of the type SoapFault if there is a problem finding the WSDL file. The URI can either be a remote file or a file stored locally on the server file systemsit just contains the description of the service, so it does not matter from exactly where it comes. So, to connect to the XMethods Currency Exchange Rate service, we will write our code as follows:

 <?php define(  'CURRENCY_SVC_WSDL',  'http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl' ); try {   $client = new SoapClient(CURRENCY_SVC_WSDL); } catch (SoapFault $sf) {   echo <<<EOM   <p align='center'>     Sorry, there was a problem connecting to the Currency     Exchange Rate service. Please try again later.   </p>   <p align='center'>     The error message was: <br/>     ({$sf->faultcode})  '{$sf->faultstring}' EOM;   exit; } ?> 

Note that the SoapFault class puts its error text and code information in two public member variables, faultcode and faultstring, which differs from the normal location used in the Exception class. We thus want to handle SoapFault exceptions in their own catch block, apart from any other exceptions.

The next step is to call the method on the Web Service we want to use. One of the most clever features of the SoapClient class is that it automagically enables you to call methods on it with the name of the methods on the server! Therefore, because we already know that we want to use the getrate method and that it expects two parameters, we can just call the method with the same name on the SoapClient we have created:

 <?php   $exchange = $client->getRate('korea', 'japan');   echo <<<EOM   To purchase 1 Korean Won, you need $exchange Japanese Yen. EOM;  ?> 

The output of this script will be something similar to the following (barring massive fluctuations in the currency markets):

 To purchase 1 Korean Won, you need 0.1031 Japanese Yen. 

The methods that you call on the server can also call generate SoapFault exceptions, so you will want to be sure to include all of your Web Service processing code within try/catch blocks, as follows:

 <?php try {   // create the client from the WSDL   $client = new SoapClient(CURRENCY_SVC_WSDL);   // invoke the getRate method.   $exchange = $client->getRate('korea', 'japan');   echo <<<EOM   To purchase 1 Korean Won, you need $exchange Japanese Yen. EOM; } catch (SoapFault $sf) {   echo <<<EOM   <p align='center'>     Sorry, there was a problem working with the Currency     Exchange Rate service. Please try again later.   </p>   <p align='center'>     The message was:<br/> '{$sf->faultstring}'. EOM;   exit; } ?> 

By wrapping all of these calls in a try/catch block, we ensure that the code will execute properly or go to the correct error handler.

Low-Level Information

Some lower-level methods on the SoapClient class might occasionally be of interest to us. These will tell us more information about the server or about the requests and responses sent between it and the client.

To get a list of all the methods available on a Web Service, you can call the __getFunctions member function, which returns an array of strings containing function signatures. For example, calling this on our Currency Exchange Rate service would result in the following output:

 array(1) {    [0]=> string(49)       "float getRate(string $country1, string $country2)"  } 

If you want to learn a little bit more about the SOAP requests and responses, the SoapClient class will let you see this informationprovided that you tell the constructor to turn on tracing, as follows:

 $client = new SoapClient(CURRENCY_SVC_WSDL,                          array('trace' => 1)); 

The second parameter to the constructor is an optional array of configuration values and options. By specifying the trace option as shown earlier, we can view headers and responses:

 <?php try {   // trace must be turned on to see requests and responses   $client = new SoapClient(CURRENCY_SVC_WSDL,                             array('trace' => 1));   // call the web service function.   $exchange = $client->getRate('china', 'zimbabwe');   // let's look at the contents of the last request.   $request = $client->__getLastRequest();   $request = htmlspecialchars($request, ENT_NOQUOTES);   echo $request; } catch (SoapFault $sf) {   echo <<<EOM   <p align='center'>     Sorry, there was a problem working with the Currency     Exchange Rate service.  Please try again later.   </p>   <p align='center'>     The message was:<br/> '{$sf->faultstring}'. EOM;   exit; } ?> 

Because the SOAP requests and responses are XML data, we cannot just send those strings to the web browser with print or echo, because the browser attempts to treat the elements within < and > as markup (and just ignore them because it does not recognize them). By calling the htmlspecialchars function (telling it to leave quotes alone), it replaces < with &lt; and > with &gt;, which lets our output look as we would expect it in the client browser, as follows (formatted for niceness):

 <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"   xmlns:ns1="urn:xmethods-CurrencyExchange"   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:getRate>       <country1 xsi:type="xsd:string">korea</country1>       <country2 xsi:type="xsd:string">japan</country2>     </ns1:getRate>   </SOAP-ENV:Body> </SOAP-ENV:Envelope> 

To see the full contents of the response, we can call the __getresponse member function on the SoapClient class.

Programmers should strive to use the trace option to the SoapClient class only for testing and debugging purposes, and otherwise leave it turned off. It is likely to have negative performance implications if it is left on all the time.




Core Web Application Development With PHP And MYSQL
Core Web Application Development with PHP and MySQL
ISBN: 0131867164
EAN: 2147483647
Year: 2005
Pages: 255

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net