= Using SOAP & REST Web Services in PHP =
PHP lets you pretty easily consume data from Web Services. There are two main types: REST and SOAP. This document outlines how to connect to a web service of each type and get some basic data from it.
== Using REST Web Services in PHP ==
REST web services are simple and easy to call, but don't provide a lot of structure. Basically, you make a standard HTTP call (either a GET or POST) to a web server, and it returns an XML document with the response (just like loading a web page, except you're getting an XML document back instead of an HTML/XHTML document). You then use PHP's standard XML processing routines (such as SimpleXML) to parse this document and get at the actual data you need.
'RESTful' web services, as they are often called, don't have to follow any particular format for either the parameters that you pass in via HTTP, or the structure of the XML document that comes back. Everything is left entirely up to the developer of the web service, which gives them (and you) a lot of flexibility, but also means there is very little consistency from one web service to the next.
=== Calling a REST Web Service ===
Calling a REST web service is easy: just create a query string, have ''curl'' grab the resulting XML document from the web service, and process it. Here, we call the Yahoo BOSS Search Service:
// Call the Yahoo BOSS search service
$query = rawurlencode('startupcto');
$appId = 'MY_YAHOO_APP_ID';
$url = "http://boss.yahooapis.com/ysearch/web/v1/{$query}?appid={$appId}&format=xml";
$c = curl_init($url);
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
$responseXML = curl_exec($c);
curl_close($c);
$response = simplexml_load_string($responseXML);
// dump out the XML object. Normally, we'd do something useful with it.
var_dump($response);
== Using SOAP Web Services in PHP ==
A SOAP web service is a little more complex than a REST web service. SOAP, a.k.a. Simple Object Access Protocol, is a W3C standard that is (theoretically) designed to standardize the exchange of data between machines, even machines running different operating systems, software, etc. The actual description of a SOAP web service interface is specified by a WSDL (a.k.a. Web Service Description Language), which tells the SOAP client what sorts of requests it can make, what format to send data in, what format to expect the returned data in, etc.
Like a REST web service, a SOAP web service operates over standard HTTP and exchanges data via XML. Unlike REST, SOAP sends/receives //both// the request and the response as an XML document, and both documents must follow the format outlined in the WSDL. (Recall that REST only sends the response as an XML document; the request is just a series of name/value parameters passed in as an HTTP GET or POST.)
PHP has a variety of SOAP implementations including [[http://pear.php.net/package/SOAP/|PEAR:Soap]] and [[http://sourceforge.net/projects/nusoap/|NuSoap]], but the best is the built-in [[http://www.php.net/soap|PHP5 ext/soap extension]].
=== Calling a SOAP Service ===
PHP5's built-in SOAP client, [[http://www.php.net/soap|ext/soap]] is a pretty easy to way to consume SOAP web services. Assuming your SOAP web service has a WSDL file, you just instantiate a SOAP client with the WSDL file, and the client will make an object with methods for each method offered by the WSDL file.
// Call the Cdyne Weather Service. Debugging mode enabled (e.g. 'trace'=>true)
$client = new SOAPClient('http://ws.cdyne.com/WeatherWS/Weather.asmx?wsdl',
array('trace' => true));
try {
$params->ZIP = '94568'; // set up parameters to pass. If we need multiple
// parameters, we can add additional elements to
// the array: $params->City = 'Dublin'
$weather = $client->GetCityWeatherByZIP($params);
} catch (SOAPFault $exception) {
// if we hit an error, print the exception and the XML we sent
print $exception;
print htmlspecialchars($client->__getLastRequest());
exit;
}
// normally, we'd do something useful with the result
var_dump($weather);
=== SOAP Debugging ===
Debugging SOAP calls is fairly annoying. The best way to do it is with the magic functions ''__getLastRequest()'', ''__getLastRequestHeaders()'', ''__getLastResponse()'', and ''__getLastResponseHeaders()''. These return a string with the actual XML that was sent (or recieved) from the SOAP call, as well as any headers sent/recieved. Note that you **must** turn on trace mode for these to work; see the example above for how to enable trace mode.
Once you have the XML, you can fiddle with the SOAP setup so that it constructs an appropriate XML document.
=== SOAP Headers - Passing Authentication Information ===
Many web services require authentication. If you're using a REST web service, you generally just pass your login, application ID, password or other authentication information as part of the call, e.g.:/my-web-service?login=bobsmith&pass=12345&action=getBlocks&type=22
If you're using SOAP, you create a 'SOAP Header'. In spirit, these are like HTTP headers: they can send information about the request that isn't part of the contents of the request (which all goes into the SOAP 'body'.)
You create the SOAP headers with the ''SOAPHeader()'' call. To see how it works, look at the advanced example, below.
=== Advanced Example: Google Keyword Tool Service ===
Here's a more advanced SOAP example, which connects to the [[http://code.google.com/apis/adwords/docs/developer/KeywordToolService.html|Google KeywordToolService]] to get keyword suggestions. It uses SOAP headers for authentication and passes multiple parameters. Note this works with the Google Sandbox, so you can try it out without having an API key.
// Set config and authentication information
$email = 'MY_ACCOUNT@SOMEWHERE.COM';
$password = 'MY_PASS';
$client_email = '';
$useragent = 'AdWords API PHP Sample Code';
$developer_token = 'MY_EMAIL_ADDR++USD';
$application_token = '';
$namespace = 'https://adwords.google.com/api/adwords/v13';
// setup a SOAP client, and assign the authentication headers to $client
$client = new SOAPClient('https://sandbox.google.com/api/adwords/v13/KeywordToolService?wsdl',
array('trace' => true));
$email = new SOAPHeader($namespace, 'email', $email);
$password = new SOAPHeader($namespace, 'password', $password);
$useragent = new SOAPHeader($namespace, 'useragent', $useragent);
$token = new SOAPHeader($namespace, 'developerToken', $developer_token);
$client_email = new SOAPHeader($namespace, 'clientEmail', $client_email);
$headers = array($email, $password, $useragent, $token, $client_email);
$client->__setSOAPHeaders($headers);
// setup parameters to pass
$params->seedKeywords->negative = false;
$params->seedKeywords->text = 'foobar';
$params->seedKeywords->type = 'Broad';
$params->useSynonyms = false;
$params->languages = 'en';
$params->countries = 'US';
try {
// make the call to the API
$variations = $client->getKeywordVariations($params);
} catch (SOAPFault $exception) {
var_dump($client->__getLastRequest());
var_dump($client->__getLastRequestHeaders());
var_dump($exception);
exit;
}
// again, normally we'd do something useful here
var_dump($variations);