PHPBuilder - Using XML, a PHP Developer's Primer: Part 5 Page 2 Page 2

RSS Twitter

Using XML, a PHP Developer's Primer: Part 5 Page 2 - Page 2

by: Adam Delves
August 22, 2008

You'll notice that the SoapClient object is created twice using the URI of the WSDL file. This does not, however, mean that two HTTP requests are made and that the WSDL file is parsed twice. PHP's soap extension also includes a WSDL caching feature, which lessens the burden of parsing WSDL files on the server. The caching feature is controlled by three directives in the php.ini configuration file, which can also be set using the ini_set() function.
  • soap.wsdl_cache_enabled – turns the caching feature on or off. On by default
  • soap.wsdl_cache_dir  - the directory where cached WSDL data is stored
  • soap.wsdl_cache_ttl – number of seconds before a cached WSDL file is considered stale and re-fetched, defaults to 86400 seconds (1 day)
With the help of the proxy generator, the SoapClient object now automatically decodes objects in the method response into their corresponding PHP types. This enables the functionality of the data types to be extended easily:


    public function 

$params->AWSAccessKeyId AMAZON_API_KEY;
$params->Request->ItemId $this->ASIN;
$params->Request->ResponseGroup 'Large'// this parameter requests detailed information on item
return $amazon->itemLookUp($params)->Items->Item;

$params->AWSAccessKeyId AMAZON_API_KEY;
$params->Request->SearchIndex 'Books';
$params->Request->Keywords 'php5 oop';
$amazon WSDLProxyGenerator::createSoapClient('''Amazon');
$result $amazon->itemSearch($params);


The modified code now uses the proxy generator class to create an instance of the soap client and extends the functionality of the Amazon_Item object to include a function which performs a detailed lookup on the item. Because the result from the itemSearch has been assigned all the appropriate data types, the new method can be called directly on each item returned.

Google API – Google Race
Sites such as Frappr, BBC News Maps and Retrievr all integrate one or more third party web services with their own application in order to enhance functionality. These sites are known as mash-ups and are becoming more common place now that popular sites such as Amazon, Google and eBay are making their API's available to developers. The next example will use PHP to create a simple example of a mash-up using the Google API.

Google Race
Google race will use the Google API to pitch two search terms against each other in a Google search. Each search will be carried out independently and the search that returns the quickest result is the winner. This is almost a complete opposite of Google Battle, where the winner is the search term with the most results.

Like Amazon, you first need to create a Google account and obtain an API Key before using their API functions. This key needs to be passed to each function. You can also download the API documentation and WSDL file. Save the WSDL file in a directory PHP has access to before beginning.

The Code
This is the code responsible for processing the search terms and executing the searches:

PHP - google_race.php:

require_once 'wsdl_proxy_generator.php';

$temr1 $term2 ''// initialise search term variables

class Google_GoogleSearchResult
    public function 
        return (int) (
/* check we have two search terms */
if(isset($_GET['term1'], $_GET['term2'])) {
/* don't forget to use stripslashes here, if magic_quotes is turned on */
$term1 $_GET['term1'];
$term2 $_GET['term2'];

    try {
/* initialize the GoogleSearch web service */
$googleSearch WSDLProxyGenerator::createSoapClient('GoogleSearch.wsdl','Google');
/* execute the searches */
$result1 $googleSearch->doGoogleSearch(API_KEY$term100,false,'',false,'','','');
$result2 $googleSearch->doGoogleSearch(API_KEY$term200,false,'',false,'','','');
/* add the terms to the two results */
$result1->term $term1;
$result2->term $term2;
/* find the winner */
if ($result1->searchTime $result2->searchTime) {
$winner $result1;
$looser $result2;
        } else {
$winner $result2;
$looser $result1;

/* calculate the length of the bars, inndicating the search times
           the winner is always 300, whereas the looser is the percentage difference */
$looser->length 300;
$winner->length = (int) (($winner->getMs() / $looser->getMs() )*300);
    } catch (
SoapFault $e) {
/* an error occured. get the error message and fualtCode */
$error $e->getMessage() . '(' $e->faultcode ')';

Notice the following:
  • The Google_GoogleSearchResult object has been extended to include a function that returns the search time in milliseconds.
  • A try...catch construct is used to catch any errors. This is a very important step, as we are relying on a third party web service. In a production environment, where possible, responses should be cached as a kind of fall back should the web service fail.
  • The length property is added to the Google_GoogleSearchResult objects.
  • No output has been produced here. This part of the script is solely responsible for the processing and execution of the searches.
Now that all the data has been collected, just append an HTML template to the bottom of the script:

PHP - google_race_template.php:

        <title>Google Race!!</title>
        <style type="text/css">
            .bar { position: relative; height: 20px;}
            .sText{    left: 5px; position: relative; top: -20px; }
            a { color: black; font-weight: bold; font-family: sans-serif; }
            #bar1 { background-color: #FF9900; }
            #bar2 {    background-color: #00FFFF; }
        <h1>Google Race</h1>
        <form method="get" action="<?php echo($_SERVER['PHP_SELF']);?>">
            <p>Search term 1 <input type="text" name="term1" value="<?php echo(htmlspecialchars($term1)) ?>" /></p>
            <p>Search term 2 <input type="text" name="term2" value="<?php echo(htmlspecialchars($term2)) ?>"/></p>
            <p><input type="submit" value="Race!!" /></p>
        <?php if(isset($winner)): // only display the results if a search was carried out ?>
            <h2>The Winner is <?php echo(htmlspecialchars($winner->term)) ?></h2>
            <div id="bar1" class="bar" style="width: <?php echo($result1->length?>px;"></div>
            <div class="sText">
                <a href="<?php echo(urlencode($term1)) ?>"><?php echo(htmlspecialchars($term1)) ?></a>
                <?php echo($result1->getMS()) ?>ms

            <div id="bar2" class="bar" style="width: <?php echo($result2->length?>px;"></div>
            <div class="sText">
                <a href="<?php echo(urlencode($term2))?>"><?php echo(htmlspecialchars($term2)) ?></a>
                <?php echo($result2->getMS()) ?>ms
        <?php elseif (isset($error)): // display the error message if an error occurred ?>
        <p><b>Error executing search. Please try again later.</b> <?php echo($error?></p>
        <?php endif; ?>   

The template uses PHP's alternate construct syntax to determine whether or not to display the result or an error message.

Performance and Security Considerations
Before taking the plunge and throwing SOAP calls into your PHP application, it is worth taking the following into consideration.
  • If you are creating a web service which only you plan to interact with, consider using XML-RPC. This is less resource intensive on the server and the payloads are smaller. SOAP should be considered where your user base is likely to be large and the API complex.
  • SOAP calls take time as they require your script to make an HTTP request, wait for its response and parse it. Keep the number of calls down to a minimum and in production environments where keeping your users waiting could mean you loose them, implement caching polices that store the responses to common SOAP calls. Some sites also offer paid subscription services that give you priority access and speed when calling their API's.
  • If you are creating a mash-up type site, ensure that you are especially careful where data that pertains to individuals is transferred to a third party web service. This “private” data can be misused by dubious sites. Read the privacy policies of sites offering web service API's carefully and if you are in any doubt at all do not use them.
  • Data received form a web serviced should be treated with the same suspicion as data received from users and needs to be validated and verified before being used.
In this article you have seen how SOAP and WSDL, in conjunction with PHP's SOAP extension, enable your web applications to interact effortlessly with third part web services. You've also seen how WSDL can be used to generate PHP class templates on the fly which can be extended to enrich the functionality of the data returned by the web service.

Next time we will be looking at two XML-based validation languages (Schema and Schematron) and we'll demonstrate how they can be used to ensure that the structure and context of an XML document is valid and its data is in the correct context.

Useful Links

« Previous Page

Comment and Contribute

Your comment has been submitted and is pending approval.

Adam Delves



(Maximum characters: 1200). You have characters left.