Book HomePHP CookbookSearch this book

12.9. Sending SOAP Requests

12.9.1. Problem

You want to send a SOAP request. Creating a SOAP client allows you to gather information from SOAP servers, regardless of their operating system and middleware software.

12.9.2. Solution

Use PEAR's SOAP classes. Here's some client code that uses the GoogleSearch SOAP service:

require 'SOAP/Client.php';

$query = 'php'; // your Google search terms

$soap = new SOAP_Client('http://api.google.com/search/beta2');

$params = array(
            new SOAP_Value('key',        'string',  'your google key'),
            new SOAP_Value('q',          'string',  $query),
            new SOAP_Value('start',      'int',     0),
            new SOAP_Value('maxResults', 'int',     10),
            new SOAP_Value('filter',     'boolean', false),
            new SOAP_Value('restrict',   'string',  ''),
            new SOAP_Value('safeSearch', 'boolean', false),
            new SOAP_Value('lr',         'string',  'lang_en'),
            new SOAP_Value('ie',         'string',  ''),
            new SOAP_Value('oe',         'string',  ''));

$hits = $soap->call('doGoogleSearch', $params, 'urn:GoogleSearch');

foreach ($hits->resultElements as $hit) {
    printf('<a href="%s">%s</a><br />', $hit->URL, $hit->title);
}

12.9.3. Discussion

The Simple Object Access Protocol (SOAP), is, like XML-RPC, a method for exchanging information over HTTP. It uses XML as its message format, which makes it easy to create and parse. As a result, because it's platform- and language-independent, SOAP is available on many platforms and in many languages, including PHP. To make a SOAP request, you instantiate a new SOAP_Client object and pass the constructor the location of the page to make the request:

$soap = new SOAP_Client('http://api.google.com/search/beta2');

Currently, two different types of communications methods are supported: HTTP and SMTP. Secure HTTP is also allowed, if SSL is built into your version of PHP. To choose one of these methods, begin your URL with http, https, or mailto.

After creating a SOAP_Client object, you use its call( ) method to call a remote function:

$query = 'php';

$params = array(
            new SOAP_Value('key',        'string',  'your google key'),
            new SOAP_Value('q',          'string',  $query),
            new SOAP_Value('start',      'int',     0),
            new SOAP_Value('maxResults', 'int',     10),
            new SOAP_Value('filter',     'boolean', false),
            new SOAP_Value('restrict',   'string',  ''),
            new SOAP_Value('safeSearch', 'boolean', false),
            new SOAP_Value('lr',         'string',  'lang_en'),
            new SOAP_Value('ie',         'string',  ''),
            new SOAP_Value('oe',         'string',  ''));

$hits = $soap->call('doGoogleSearch', $params, 'urn:GoogleSearch');

The $params array holds a collection of SOAP_Value objects. A SOAP_Value object is instantiated with three arguments: the name, type, and value of the parameter you're passing to the SOAP server. These vary from message to message, depending upon the SOAP functions available on the server.

The real action happens with the SOAP_Client::call( ) method, which takes a few arguments. The first is the method you want the server to execute; here, it's doGoogleSearch. The second argument is an array of parameters that gets passed to the function on the SOAP server. The third argument, urn:GoogleSearch, is the SOAP namespace; it allows the server to know that doGoogleSearch belongs in the GoogleSearch namespace. With namespaces, a more generally named search method doesn't cause a conflict with another more specific search method.

There's a fourth parameter that's unused here: soapAction. If you want to provide the SOAP server with a URI indicating the intent of the request, you can add one here. Unfortunately, the definition of the word "intent" varies from implementation to implementation. The current consensus is that soapAction shouldn't be used until its meaning is further clarified. The PEAR SOAP server doesn't use this field, but other vendors may assign their own meanings.

Upon successful execution, the function returns an object containing the server's response. If an error occurs, the function returns a PEAR_Error object. Google returns all sorts of information, but here we just iterate through the $resultElements array and pull out the URL and title of each hit for display:

foreach ($hits->resultElements as $hit) {
    printf('<a href="%s">%s</a><br />', $hit->URL, $hit->title);
}

This results in:

<a href="http://www.php.net/"><b>PHP</b>: Hypertext Preprocessor</a>
<a href="http://www.php.net/downloads.php"><b>PHP</b>: Downloads</a>
<a href="http://phpnuke.org/"><b>PHP</b>-Nuke</a>
<a href="http://www.phpbuilder.com/">PHPBuilder.com</a>
<a href="http://php.resourceindex.com/">The <b>PHP</b> Resource Index</a>
<a href="http://www.php.com/"><b>PHP</b>.com: Home</a>
<a href="http://www.php.org/"><b>PHP</b>.org</a>
<a href="http://php.weblogs.com/"><b>PHP</b> Everywhere:</a>
<a href="http://www.php3.org/"></a>
<a href="http://gtk.php.net/"><b>PHP</b>-GTK</a>

You can also use Web Services Definition Language (WSDL), to implement the request. With WSDL, you don't need to explicitly enumerate the parameter keys or the SOAP namespace:

require 'SOAP/Client.php';

$wsdl_url = 'http://api.google.com/GoogleSearch.wsdl';
$WSDL = new SOAP_WSDL($wsdl_url);
$soap = $WSDL->getProxy( );

$hits = $soap->doGoogleSearch('your google key',$query,0,10,
                               true,'',false,'lang_en','','');

This code is equivalent to the longer previous example. The SOAP_WSDL object takes a URL for the GoogleSearch WSDL file and automatically loads the specification from that URL. Instead of making $soap a SOAP_Client, call SOAP_WSDL::getProxy( ) to create a GoogleSearch object.

This new object has methods with the same name as the GoogleSearch SOAP methods. So, instead of passing doGoogleSearch as the first parameter to SOAP_Client::call( ), you call $soap->doGoogleSearch( ). The $params array becomes the arguments for the method, without any array encapsulation or SOAP_Value instantiations necessary. Also, because it's set in the WSDL file, the namespace doesn't need to be specified.

12.9.4. See Also

Recipe 12.10 for more on SOAP servers; Recipe 20.11 for an example of a SOAP client in a PHP-GTK application; PEAR's SOAP classes at http://pear.php.net/package-info.php?package=SOAP; Programming Web Services with SOAP, by Doug Tidwell, James Snell, and Pavel Kulchenko (O'Reilly); information on the Google SOAP service at http://www.google.com/apis/.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.