Recipe 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
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.
$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.