Archive for the ‘SOA’ tag
Writing SOA applications with PHP
Lately I’ve been working a lot with data integration between several web applications, and a natural choice for the integration was to use a Service Oriented Architecture (SOA). I’ve built both SOA servers and clients before using the SOAP approach, which is a superb way of transferring data when not knowing who the user of the service is, or when you are a client of such a service. However in this setting I knew who the user was, I knew what the service would be used for, also had the chance to write both the client and server.
The choice fell on a simple implementation using the JSON (JavaScript Object Notation) data structure. This is really easy using the built in json library in php. The server use the json_encode() function and the implemented sub class of the client use the json_decode() function.
To simplify this further I implemented two abstract classes, a ServiceServer class and a ServiceClient class. The service server class contained a very simple displayJSONResult function, which sets the correct header, encode the data as json data and echo the data.
The service client class has two main functions, doGetRequest and doPostRequest, both functions use the cURL library in PHP.
Server
-
<?php
-
-
abstract class ServiceServer
-
{
-
-
public function __construct(){}
-
-
protected function displayJSONResult($data)
-
{
-
header('Content-type: text/plain');
-
-
echo json_encode($data);
-
-
exit();
-
}
-
}
Client
-
<?php
-
-
/**
-
* ServiceClient
-
*
-
*
-
* @author Kristian Lunde
-
*
-
*/
-
-
class ServiceClient
-
{
-
-
public function __construct(){}
-
-
/**
-
* do a post request to a service
-
*
-
* the params parameter must be a string with the format:
-
* key=val&key2=val2&key3=val3
-
*
-
* @param string $url
-
* @param string $params
-
*/
-
protected function doPostRequest($url, $params)
-
{
-
$ch = curl_init($url);
-
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER , false);
-
curl_setopt($ch, CURLOPT_RETURNTRANSFER , true);
-
curl_setopt($ch, CURLOPT_POST , 1);
-
curl_setopt($ch, CURLOPT_POSTFIELDS , $params);
-
$result = curl_exec($ch);
-
curl_close($ch);
-
return $result;
-
}
-
-
/**
-
* do a get request to a service
-
*
-
* @param string $url
-
*
-
* @return mixed
-
*/
-
protected function doGetRequest($url)
-
{
-
$ch = curl_init($url);
-
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER , false);
-
curl_setopt($ch, CURLOPT_RETURNTRANSFER , true);
-
$result = curl_exec($ch);
-
curl_close($ch);
-
return $result;
-
}
-
-
}
Example
To illustrate the easiness and simplicity of this SOA approach I written a small example. In this example the server finds the country of a city using POST parameters or it can find cities using the country as a GET parameter.
Example server
-
<?php
-
-
/**
-
* Example of using the ServiceServer class
-
*
-
* Returns countries or cities
-
*
-
* @author Kristian Lunde
-
*/
-
-
require_once('ServiceServer.php');
-
-
class ExampleServer extends ServiceServer
-
{
-
-
-
-
public function __construct()
-
{
-
$this->countries = array('norway' => array('Oslo',
-
'Trondheim',
-
'Bergen',
-
'Halden',
-
'Sarpsborg',
-
'Hammerfest'),
-
'sweden' => array('Stockholm',
-
'Gothenburg',
-
'Karlstad'),
-
'england' => array('London',
-
'Newcastle',
-
'Bath',
-
'Liverpool'));
-
-
-
if(isset($_GET['country']))
-
{
-
$this->findCitiesByCountry(trim($_GET['country']));
-
}
-
-
if(isset($_POST['city']))
-
{
-
$this->findCountryByCity(trim($_GET['city']));
-
}
-
}
-
-
public function findCitiesByCountry($country)
-
{
-
$cities = 'Not found';
-
$country = strtolower($country);
-
-
if(isset($this->countries[$country]))
-
{
-
$cities = $this->countries[$country];
-
}
-
-
$this->displayJSONResult($cities);
-
}
-
-
public function findCountryByCity($city)
-
{
-
$country = 'Not found';
-
-
$break = false;
-
foreach($this->countries as $key => $val)
-
{
-
for($i = 0, $count = count($val); $i < $count; $i++)
-
{
-
if($city == $val[$i])
-
{
-
$country = $key;
-
$break = true;
-
break;
-
}
-
}
-
-
if($break)
-
{
-
break;
-
}
-
}
-
-
$this->displayJSONResult($country);
-
}
-
}
-
-
$obj = new ExampleServer();
-
?>
Example client
-
<?php
-
/**
-
* Example of using the ServiceClient class
-
*
-
* does a request to the ExampleServer
-
*
-
* @author Kristian Lunde
-
*/
-
-
require_once('ServiceClient.php');
-
-
class ExampleClient extends ServiceClient
-
{
-
public function __construct()
-
{
-
$this->getCities('Norway');
-
$this->getCounty('Bath');
-
}
-
-
public function getCities($country)
-
{
-
$url = 'http://files.klunde.net/files.klunde.net/ExampleServer.php?country=' . $country;
-
echo $this->doGetRequest($url);
-
}
-
-
public function getCountry($city)
-
{
-
$url = 'http://files.klunde.net/files.klunde.net/ExampleServer.php';
-
$params = 'city=' . $city;
-
-
echo $this->doPostRequest($url, $params);
-
}
-
}
-
$obj = new ExampleClient();
-
?>
I’m quite satisfied with this implementation because it is so easy to maintain and even more important, implementing new services and clients for the services is straight forward and supports rapid development.