Interacting with a PHP Web Service

information

Interacting with a PHP Web Service

In this article I’ll show you how to create a simple PHP Web Service and how to interact with it.

A Web Service is just a component installed on a web server or just a PC that can be invoked using its public methods to exchange data between two or more PCs.
Web Services are everywhere and you might use them without even know it and many of the social media leaders such as Twitter, Amazon, Facebook, Microsoft, etc are exposing them to the internet so we can have a quicker access to information than just browsing and browsing the internet searching for it.

The most common way of accessing a web service is using the GET method, but some of them will only accept POST requests. While the most spreaded response method is XML some of them can return just plain text while others can output a JSON encoded string.

The example presented in this article will be focused on interacting with a web service that outputs a JSON encoded string.

Our web service is just a class, named DemoWebService, which only responds to POST requests. It has three public methods that can be invoked, each of them returning a different value.

The most important action is happening in the class’s constructor, where we check the request method, validate and sanitize the request and then calling the specified method as you can see in the example below:

//@ .ctor
public function __construct()
{
    //@ VALIDATE THE REQUEST
    if ( $_SERVER['REQUEST_METHOD'] <> 'POST')
    {
        $this->Reply('Error', 'Invalid request');
    }
    //@ SANITIZE REUEST
    $_POST = array_map('strip_tags', $_POST);
 
    //@ CHECK THE PROVIDED METHOD
    $callMethod = (empty($_POST['method']) ? '' : $_POST['method']);
    if (empty($callMethod))
    {
        $this->Reply('Error', 'Method is missing!');
    }
    //@ IS THE METHOD AVAILABLE?
    if ( ! is_callable(array($this, $callMethod)))
    {
        $this->Reply('Error', 'Invalid method provided!');
    }
    //@ GET ARGS
    $arg = (empty($_POST['arg']) ? '' : $_POST['arg']);
    call_user_func(array($this,$callMethod), $arg);
}

If you access the DemoWebService.php file directly, you will get a JSON response that informs you that you’re accessing it the wrong way:

{"title":"Error","message":"Invalid request"}

Next, there is a utility function that we’ll be using to create the response:

	//@ exits the JSON string
	protected function Reply( $title, $message )
	{
		$response = array('title' => $title, 'message' => $message);
		exit( json_encode($response) );
	}

As you can see in the code above, our response will consists of two fields: title and message.

Next, there are the web service’s public methods, that you can invoke and retrieve whatever information they return:

	/*!
	| @public
	| @desc Display the Hello $name! message
	*/
	public function Hello( $name )
	{
		if (empty($name) || ! is_string($name))
		{
			$this->Reply('Error', 'The name is missing or is not a string!');
		}
		$name = strip_tags($name);
		$this->Reply('Server says:', 'Hello '.$name.'!');
	}
 
	/*!
	| @public
	| @desc Display the current GMT time
	*/
	public function GetServerTime()
	{
		$message = 'GMT time is: '.gmdate("l H:i:s A", time());
		$this->Reply('', $message);
	}
 
	/*!
	| @public
	| @desc Display the currently available methods
	*/
	public function Describe()
	{
		$this->Reply('Available methods:', 'Hello, GetServerTime, Describe');
	}

At the end of that file we need to instantiate the class so whenever this web service is requested by a client it will start its cycle: validating the request, sanitizing data, etc and then respond to the client’s request:

//@ INSTANTIATE THE WEB SERVICE
$dws = new DemoWebService();

Basically, that’s all that happens server-side, now let’s have a look at the code we need client-side. This page will allow us to interact with the web service using a web form and a very simple javascript script that we’ll use to make asynchronous requests. I’ll use the jQuery library for that.

So this is how our page looks like:

web service

The javascript routines used for this example are pretty basic as you can see in the example below:

//@ UTILITY METHOD TO INTERACT WITH THE WEB SERVICE
jQuery.callWebService = function( methodName, argument, timeout )
{
	if (parseInt(timeout) < 2000) { timeout = 2000; }
 
	//@ CALL WEB SERVICE'S METHODS
	$.ajax({
		'timeout': timeout,
		'url': 'http://localhost/test/v7n-tech/DemoWebService.php',
		'data': { 'method': methodName, 'arg': argument },
		'cache': false,
		'type': 'post',
		'success': function(data)
		{
			//@ MAKE SURE THIS IS A VALID JSON RESPONSE
			try { data = $.parseJSON(data); }
			catch(err) { alert('Error retrieving data!'); return false; }
 
			try {
				//! Make sure the expected fields are in the response
				if (data.title.length == null || data.message.length == null)
				{
					return false;
				}
			}
			catch(err) {
				alert('Invalid server response!');
				return false;
			}
			//@ Display the web service's response
			var response = '';
			if (data.title != '')
			{
				response += data.title + ' ';
			}
			if (data.message != '')
			{
				response += data.message;
			}
			alert(response);
		},
		'error': function(req,status,err) { alert('Error: '+status); }
	});
	/*[ END AJAX ]*/
};
 
/*[ START ONLOAD ]*/
jQuery('document').ready(function($)
{
	$('#button1').click(function(e)
	{
		e.stopPropagation();
		var name = $.trim( $('#name-textbox').val() );
		if (name.length < 1) {
			alert('Please enter your name!');
		}
		else
		{
			//@ Call web service
			$.callWebService('Hello', name);
		}
	});
	/*[ END BUTTON1.CLICK ]*/
 
	$('#button2').click(function(e)
	{
		//@ Call web service
		$.callWebService('GetServerTime');
	});
	/*[ END BUTTON12.CLICK ]*/
 
 
	$('#button3').click(function(e)
	{
		//@ Call web service
		$.callWebService('Describe');
	});
	/*[ END BUTTON3.CLICK ]*/
});
/*[ END ONLOAD ]*/

Because all buttons will use the ajax feature I’ve created the callWebService helper method that will handle each of the AJAX requests initiated when any of the form’s buttons is clicked.

At the moment, this code will only work if the DemoWebService resides on your own PC because of the Same origin policy that applies to javascript. To overcome this inconvenience you’re going to need a proxy, that is a PHP script that will intermediate the request. Maybe I’ll show you how to do that in another article.

You can download the source code here: [download link]

Thanks for reading!

Costin Trifan
Costin Trifan is a 32 years old web developer from Romania. He currently finds PHP more interesting than any other thing in his life and spends way too much time in front of his PC creating websites and scripts like the IrisMVC framework in the hope they’ll help other people just as much as they help him.

You can easily reach him via his blog, or through social media such as Twitter or in the coding section of the v7n forums (most likely).

  1. CricketCricket03-15-2011

    Thank you so very much for taking the time to guest author a post here on the V7N! You did an absolutely wonderful job. I also appreciate all the help teaching me the best way to display code within a post. The WP-Syntax plugin rocks! 🙂

    • koskos03-15-2011

      It’s impossible to say no to such a wonderful person like you, ma’am! It’s an honor for me to be featured on one of the v7n’s blogs!

      I only hope that the rest of them will be even more interesting! 🙂

      Thank you very much, Cricket!

      XO

Leave a Reply