En este ejemplo vamos a intentar explicar cómo realizar un simple
web service que utiliza
JSON como formato de intercambio, en lugar del clásico
XML que utilizan los web services
SOAP. Con JSON además de su sencillez para manejarlo con
Javascript y
PHP tenemos un formato ligero y muy simple de notación literal.
Lo primero que tendremos en cuenta es que el formato de intercambio será JSON, por lo que la información enviada y recibida será de tipo
application/json.
El código de la clase del web service y la implementación de una función básica para obtener la hora del servidor sería este:
class JSON_WebService {
private $methods, $args, $strcall;
public function __construct($rawData) {
$this->strcall = str_replace($_SERVER["SCRIPT_NAME"]."/", "", $_SERVER["REQUEST_URI"]);
$this->args = $rawData;
$this->methods = array();
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
header('Cache-Control: no-cache, must-revalidate');
header('Content-type: application/json; charset=utf-8');
}
public function Register($name) {
$this->methods[$name] = true;
}
public function Remove($name) {
$this->methods[$name] = false;
}
private function call($name, $args) {
if ($this->methods[$name] == true) {
$result = call_user_func_array($name, $args);
return json_encode($result);
}
}
function start() {
try{
if(!function_exists($this->strcall))
throw new Exception("Function '".$this->strcall."' does not exist.");
if (!$this->methods[$this->strcall])
throw new Exception("Access denied for function '".$this->strcall."'.");
header("HTTP/1.0 200 OK");
print $this->call($this->strcall, json_decode($this->args));
}
catch(Exception $e){
header("HTTP/1.0 500 Internal server error");
print json_encode(
array(
"message" => $e->getMessage(),
"code" => $e->getCode(),
"file" => $e->getFile(),
"line" => $e->getLine(),
"stackTrace" => $e->getTrace(),
"status" => array("message" => "Internal server error", "code" => "500")
)
);
}
}
}
//Obtiene el contenido de la solicitud POST
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
//Instancia de la clase JSON_WebService
$server = new JSON_WebService($HTTP_RAW_POST_DATA);
//Registra los metodos del servicio web
$server->register("getServerTime");
//Inicializa el servicio
$server->start();
//Define los metodos del servicio web
function getServerTime($format){
return date($format);
}
Para la llamada al web service implementamos una clase cliente. Realmente lo que hacemos es utilizar las funciones de la librería
libcurl pasándole por
POST los parámetros a la página PHP que hace de servidor. El código lo tenemos a continuación:
class JSON_WebClient{
private $URL;
public function __construct($url){
$this->URL = $url;
}
public function call($method, $args, $successCallback = false, $errorCallback = false){
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, Array("Content-Type: application/json"));
curl_setopt($ch, CURLOPT_URL, $this->URL."/".$method);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($args));
$resposeText = curl_exec($ch);
$resposeInfo = curl_getinfo($ch);
if($resposeInfo["http_code"] == 200){
if($successCallback)
call_user_func($successCallback, json_decode($resposeText));
} else {
if($errorCallback)
call_user_func($errorCallback, json_decode($resposeText));
}
}
}
Y la llamada la tendríamos con este código:
$client = new JSON_WebClient("http://localhost/service.php");
$client->call("getServerTime", array("format"=>"d/m/o H:i:s"), "onSucceededCallback", "onErrorCallback");
function onSucceededCallback($result){
print $result;
}
function onErrorCallback($error){
print "Error: ".$error->{"message"};
}