Using REST Web Services in PHP

Back in the day (the day being February 2001) all the cool kids were exchanging their data as XML over HTTP in an effort to break free from the hellish world of client side ODBC drivers (Mac OS 9 any one?) and firewalls blocking ports.

This revolution had one downside though: there was no common XML schema for all this data which meant that every implementation was different and every project needed a debate over what schema to use and a rigid spec that had to be adhered to.

Out of this recipe for disaster formal web services like SOAP and XML-RPC were born. With a strict XML schema and a mandatory documentation language, SOAP allowed developers to be completely abstracted from serialising/de-serialising their data and a lot of libraries let SOAP methods transparently map to native methods… which is great!

Then there was a curve ball in the shape of REST. Representational State Transfer is similar to SOAP/XML-RPC, it still exchanges data via http but isn’t necessarily as rigid in it’s implementation… it uses URL GET data to send parameters, the emphasis being placed on a common api for exchanging data between everything from HTML forms, JSON apps and RPC Web Services - it’s very light weight but a bit vague. More can be read here.

Below is an example PHP Class for consuming a simple implementation of a REST web-service, it assumes that the server is expecting a conventional HTTP query string which won’t be compatible with some services and it also doesn’t de-serialise the returned data - that’s up to you!


<?php

class RestServiceClient {

	private $url; //the URL we are pointing at

	private $data = array(); //data we are going to send
	private $response; //where we are going to save the response

	public function __construct($url) {
		$this->url = $url;
	}

	//get the URL we were made with
	public function getUrl() {
		return $this->url;
	}

	//add a variable to send
	public function __set($var, $val) {
		$this->data[$var] = $val;
	}

	//get a previously added variable
	public function __get($var) {
		return $this->data[$var];
	}

	public function excuteRequest() {
		//work ok the URI we are calling
		$uri = $this->url . $this->getQueryString();

		//get the URI trapping errors
		$result = @file_get_contents($uri);

		// Retrieve HTTP status code
		list($httpVersion, $httpStatusCode, $httpMessage) = explode(' ', $http_response_header[0], 3);

		//if we didn't get a '200 OK' then thow an Exception
		if ($httpStatusCode != 200) {
			throw new Exception('HTTP/REST error: ' . $httpMessage, $httpStatusCode);
		} else {
			$this->response = $result;
		}
	}

	public function getResponse() {
		return $this->response;
	}

	//turn our array of variables to send into a query string
	protected function getQueryString() {

		$queryArray = array();

		foreach ($this->data as $var => $val) {
			$queryArray[] = $var . '=' . urlencode($val);
		}

		$queryString = implode('&', $queryArray);

		return '?' . $queryString;
	}
}

?>

Usage:

<?php

$rws = new RestServiceClient('http://api.search.yahoo.com/ImageSearchService/V1/imageSearch');

$rws->query = 'Donnie Darko';
$rws->results = 8;
$rws->appid = 'YahooDemo';

$rws->excuteRequest();
// calls: http://api.search.yahoo.com/ImageSearchService/V1/imageSearch?query=Donnie+Darko&results=8&appid=YahooDemo
var_dump($rws->getResponse());

?>

Comments

4 Responses to “Using REST Web Services in PHP”

  1. Sk on August 7th, 2008 10:46 am

    Hi,

    Thanks for good exmple.

    What would be the content of $rws->getResponse() whether it should be xml or it can be anything?

    If its xml then dont this called SOAP instead REST?

  2. Darko on August 7th, 2008 11:51 am

    Hey Sk,

    Thanks for your comment!

    The response could be anything… normally it would be data in some some kind of mark up language.

    The big difference between REST and SOAP is that SOAP is sent data as XML using POST, rather than GET, and returns XML complying to a very strict DTD (which some consider bloated) where as REST could return anything - even just ‘1′ or ‘0′, making it much lighter weight.

    Hope that makes sense,

    Dk0

  3. joseph on October 14th, 2008 9:24 am

    Hi,

    Thank you for your wonderful posting. It helps me to start with REST service on my project.

    I got one warning during the development process and is below:

    ———————————————

    A PHP Error was encountered

    Severity: Warning

    Message: urlencode() expects parameter 1 to be string, object given

    Filename: controllers/manager.php

    Line Number: 109

    I used your code in CodeIgniter and the error is in the function

    protected function getQueryString()

    Line: $queryArray[] = $var . ‘=’ . urlencode($val);

    —————————————————

    Clarification:
    ————–

    1. In the give example, you are calling the Yahoo API for image search and the parameters are appended to the URL itself. I want to pass an XML file to the calling class, where I can store all the paramters with their values. Is that possible?

    Or we can store the xml in any common location and the REST class (Yahoo API) can read it from there?

    2. Another doubt is the cycling of the process or the use of Two APIs at a time. That means, first time I called a page and it uses one API to get some data. If data is returned, then the called page use that data for future process and return the result..

    Does this possible? or I am ignorant of REST ?

    Thank You..
    Joseph.

  4. Darko on October 14th, 2008 7:58 pm

    Hey Joseph,

    Check the $val variable is a string, or if it’s an object make sure it has a toString magic method…

    Hope that’s some help,

    Dk0

Leave a Reply




Singularity?