SOAP – Server y Cliente en PHP con Nusoap

Introducción

Antes que nada no voy a entrar en detalles del protocolo sino de como implementarlo con php, pero me consta que lo correcto es al menos aclarar, aunque sea repetitivo, que significan estas siglas.
Sin meterme mucho en el tema puedo contarles que SOAP son las siglas de siglas de Simple Object Access Protocol, el cual obviamente es un protocolo que fue creado por varios grosos (MS, IBM, Etc), y su fuente de datos es el XML con un diseño que cumple el patrón Cabecera-Desarrollo y que actualmente está auspiciado por la W3C.

Es un protocolo que se usa mucho para webservices, y por lo tanto, para hacer una petición desde un cliente se necesita una respuesta desde un servidor.

Si lo que se desea es crear un cliente, el cual hace peticiones a un SOAP servidor que no es nuestro, la tarea será más simple. Ahora, si lo que se desea es tener un cliente, ya el enfoque es otro aunque nada complicado, ya lo verán.

Lo único a tener en cuenta es que debemos contar con una directiva del php.ini indispensable para su funcionamiento, ésta es la directiva always_populate_raw_post_data la cual debe estar en ON.

Otra necesidad es poder tener algo con cual poder escribir y parsear este xml, para ellos tenemos dos opciones: una es usar las funciones que nos da php al habilitar una dll, para más información de esto pueden ver la documentación de php en php.net/soap; dos, usar nusoap, una clase hecha para esta tarea, la cual permite crear cliente, servidor.

Para ser más prácticos les mostraré un simple ejemplo de un servidor y un cliente.

Primer paso, tener nuestro servidor.

Para comenzar no podremos avanzar sin antes tener nuestra querida librería nusoap. En este ejemplo he usado la versión 0.7.2, la cual pueden descargar desde aqui.

Una vez en sus máquinas, pueden descomprimir el directorio lib del zip en un directorio nuestro llamado “include” (o el nombre que más les guste). No es necesario mover los ejemplos, pero si gustan pueden darle una mirada, cosa que nunca está de más.

Para usar esta clase todo lo que debemos hacer en nuestro php es incluirla. Entonces, creamos un php que se llame server.php, y en él escribimos:

<?
require_once(’includes/nusoap.php’);
?>

Ahora bien, necesitamos crear un objeto del tipo servidor, eso es simple, lo hacemos instanciando el método soap_server, nos quedaría algo así:

<?
require_once(’includes/nusoap.php’);
$server = new soap_server;
?>

Bien, hasta acá venimos bárbaro, pero me olvide de comentarles que la tarea de un servidor es la de servir. Claro que este comentario es obvio!, pero para el caso no se preguntan que es lo que servirá mi servidor? Pues no más que datos es la respuesta que pensarán y es correcta. El tema es nuestros datos se servirán en base a una petición del cliente mediante funciones, tal cual cuando usamos funciones nuestras del tipo getUser( $id ).

Entonces, para procesar de manera simple una petición haremos una función en php, una simple función, por ejemplo:

function hola( $name ){
return “Hola {$name}”;
}

De más esta decir que puedo tener todas las funciones necesarias y estas estar en un archivo aparte, pero para el ejemplo es lo mismo.

Ahora bien, aquí viene lo interesante del servidor y es que registraremos en nuestro SOAP la función que acabamos de crear de la siguiente manera:

$server->register( ‘hola’ );

Solo nos resta tomar toda la petición del cliente, y esto lo haremos con la variable de php llamada $HTTP_RAW_POST_DATA la cual contiene el post en bruto. En caso de no contar con la directiva always_populate_raw_post_data en ON como dijimos, pueden intentar setearla de la siguiente manera, aunque no garantizo su funcionamiento ya que depende de otras configuaraciones del servidor web y OS:

$rawPost = strcasecmp($_SERVER[‘REQUEST_METHOD’], ‘POST’) == 0? (isset($GLOBALS[‘HTTP_RAW_POST_DATA’])? $GLOBALS[‘HTTP_RAW_POST_DATA’] : file_get_contents(”php://input”)) : NULL;

Una cosa que no esta de más es validar el dato que nos manda el cliente, para esto podemos modificar la función para crear un fault, quedando así:

function hola( $name ){
return empty( $name ) ? new soap_fault(’Client’,”,’Ingrese un nombre válido’) : “Hola ” . $name;
}

Ahora, como está todo en partes, para sintetizar quedaría así nuestro achivo que llamaremos para el ejemplo servidor.php:

<?
$rawPost = strcasecmp($_SERVER[‘REQUEST_METHOD’], ‘POST’) == 0? (isset($GLOBALS[‘HTTP_RAW_POST_DATA’])? $GLOBALS[‘HTTP_RAW_POST_DATA’] : file_get_contents(”php://input”)) : NULL;
require_once(’includes/nusoap.php’);
$server = new soap_server;
$server->register(”hola”);
$server->service($rawPost);
function hola( $name ){
return empty( $name ) ? new soap_fault(’Client’,”,’Ingrese un nombre válido’) : “Hola ” . $name;
}
?>

Solo resta nuestro cliente para poder probarlo, que como les decía es mucho más simple.
El mismo todo lo que debe hacer es llamar a nuestro servidor haciendo llamada a la función hola y pasarle un parámetro que es lo que ésta espera.

Para ellos creamos cliente.php, incluimos nuevamente la clase nusoap, e instanciamos al método soapclient pasándole como parámetro la url de nuestro servidor. Una vez creado el objeto haremos un método call a nuestra función hola y le pasaremos los parámetros necesarios, tan simple como esto:

<?
require_once(’includes/nusoap.php’);
$soapclient = new soapclient(’http://tudominio.com/nusoaptest/server.php’);
echo $soapclient->call( ‘hola’ , array(’name’ => ‘Mundo’) );
?>

Ya tenemos nuestro servidor y nuestro cliente…

Con el servidor podemos servir o procesar peticiones de un cliente cualquiera. Con nuestro cliente podemos llamar a un servidor y usar sus prestaciones.