WebServices con NuSOAP en PHP - Ejemplo 1


Ya hace un tiempo realice un artículo sobre servicios web con PHP (utilizando NuSOAP), el mismo se puede acceder en WebServices con PHP usando NuSOAP, el mismo ya ha quedado un poco obsoleto debido a que el servidor que alojaba el webservice ya no lo contiene más. Por tal motivo y debido a que uno de los inconvenientes principales cuando uno se esta iniciando en el tema de los webservices con PHP, principalmente con NuSOAP, es encontrar como realizar el módulo servidor. En este primer post, decidí subir un ejemplo sencillo de comunicación entre un módulo servidor que provee expone una función, y un módulo cliente que las consume.

Introducción al ejemplo

No voy a exponer demasiados detalles con respecto a que son los WebServices, para ello pueden acceder al enlace que mencione anteriormente (WebServices con PHP usando NuSOAP). Solamente me limitare a explicar un poco el funcionamiento del mismo. Para el ejemplo, estoy utilizando la siguiente estructura de directorios

Siendo, nusoap_server_ej1.php el servidor de nustro WebService con NuSOAP, y nusoap_client_ej1.php el cliente.

Requerimientos

Los requerimientos para poner en funcionamiento el ejemplo son simplemente NuSOAP y tener algún servidor de sitios web (como puede ser Apache) corriendo PHP. Para todos aquellos que actualmente no tienen un servidor corriendo, pueden descargar XAMPP que es un servidor apache con PHP (también trae otras funcionalidades, pero estas 2 son las que importan para nuestro ejemplo) que solo se descarga, se descomprime, y con solo ejecutar un archivo, se inicia el servidor Apache con PHP en nuestra computadora, sin necesidad de mayores dolores de cabeza (Funciona tanto para Windows, como para OS-X).

Módulo servidor

El servidor de este ejemplo es muy sencillo, tan sencillo como el siguiente código:
<?php
// Incorporar la biblioteca nusoap al script, incluyendo nusoap.php (ver imagen de estructura de archivos)
require_once('nusoap/lib/nusoap.php');
// Modificar la siguiente linea con la direccion en la cual se aloja este script
$miURL = 'http://pruebas.orlandobrea.com.ar/nusoap_ej1';
$server = new soap_server();
$server->configureWSDL('ws_orlando', $miURL);
$server->wsdl->schemaTargetNamespace=$miURL;

/*

  • Ejemplo 1: getRespuesta es una funcion sencilla que recibe un parametro y retorna el mismo
  • con un string anexado
    */
    $server->register('getRespuesta', // Nombre de la funcion
    array('parametro' => 'xsd:string'), // Parametros de entrada
    array('return' => 'xsd:string'), // Parametros de salida
    $miURL);
    function getRespuesta($parametro){
    return new soapval('return', 'xsd:string', 'soy servidor y devuelvo: '.$parametro);
    }

// Las siguientes 2 lineas las aporto Ariel Navarrete. Gracias Ariel
if ( !isset( $HTTP_RAW_POST_DATA ) )
$HTTP_RAW_POST_DATA = file_get_contents( 'php://input' );

$server->service($HTTP_RAW_POST_DATA);
?>


El ejemplo es bastante
sencillo, simplemente registra una función que recibe un
parámetro y devuelve dicho parámetro con un texto
adelante ("soy el servidor y devuelvo: ". El parámetro de
entrada a la función es del tipo String, y la
función también retorna un String.

Anteriormente mencione que no
iba a detallar demasiado en código, ya que como pueden ver
el mismo esta comentado, y creo que es bastante entendible.

Como podemos ver en el ejemplo,
la complejidad mayor en crear el módulo servidor para un
webservice, es crear la estructura de datos del mismo y sus tipos (ver
$server->register() en el ejemplo). Si bien el ejemplo es muy
sencillo, podemos ver que tanto los datos que el webservice recibe,
como los que retorna, deben ser especificados en los tipos de datos
predefinidos en XML para crear un Schema (xsd:string, xsd:int, etc.).
En los próximos ejemplos que vaya subiendo de webservices
con NuSOAP se podrá ver más en detalle algunos
tipos de datos, y también como crear estructuras complejas
(retornar objetos, o listas). Por el momento solo estamos recibiendo un
String (xsd:string y retornamos otro entero (xsd:string).

En el ejemplo se puede ver que
la función a la cual el webservice llama para atender la
petición, en este caso getRespuesta, debe codificar la
respuesta en el tipo de datos esperado. En este caso definimos que la
función retornaría un xsd:string, por lo que
debemos crear un soapval con el tipo de datos esperado.

¿Como se enlazan los datos recibidos por el servidor con nuestra función?

Cuando definimos los parámetros, tanto de entrada, como de respuesta, a los mismos le asignamos un nombre. Por ejemplo al parámetro de entrada le asignamos el nombre "parametro" (si, no es muy original, pero sirve para entender el ejemplo). Y el parámetro de salida, o retorno, lo llamamos "return". Entonces lo que hará NuSOAP es enlazar el parámetro de entrada a la función getRespuesta cuyo nombre es "parametro", con el valor que tome el "parametro" definido en el webservice. Voy a mostrár graficamente el enlace, para que sea más sencilla su visualización:
 

¿Que pasa si mi función NO recibe parámetros?

Simplemente modificariamos el código de:
$server->register('getRespuesta', // Nombre de la funcion
 array('parametro' => 'xsd:string'), // Parametros de entrada
 array('return' => 'xsd:string'), // Parametros de salida
 $miURL);
al siguiente código:
$server->register('getRespuesta', // Nombre de la funcion
 array(), // Parametros de entrada
 array('return' => 'xsd:string'), // Parametros de salida
 $miURL);
y obviamente a la función que hacemo referencia (getRespuesta) no debería recibir parámetros, por lo que pasaría de:
function getRespuesta($parametro){
a:
function getRespuesta(){

El cliente

Para este ejemplo que estoy mostrando, el cliente tiene un poco más de código que el servidor, para ejemplos un poco más complejos, el servidor comienza a ser un poco más largo, y el cliente mantiene apróximadamente la misma longitud. ¿Por que pasa esto? sencillo, a medida que el ejemplo se hace más complejo, se necesitán funciones más complejas en el servidor y principalmente, definir que los datos que vamos a utilizar también son más complejos. Pero eso lo dejaremos para futuros ejemplos que vaya subiendo al blog. Ahora nos concentraremos en el cliente, cuyo código es el siguiente:
<?php
// Incluimos la biblioteca de NuSOAP (la misma que hemos incluido en el servidor, ver la ruta que le especificamos)
require_once('nusoap/lib/nusoap.php');
// Crear un cliente apuntando al script del servidor (Creado con WSDL) - 
// Las proximas 3 lineas son de configuracion, y debemos asignarlas a nuestros parametros
$serverURL = 'http://pruebas.orlandobrea.com.ar';
$serverScript = 'nusoap_server_ej1.php';
$metodoALlamar = 'getRespuesta';

// Crear un cliente de NuSOAP para el WebService
$cliente = new nusoap_client("$serverURL/$serverScript?wsdl", 'wsdl');
// Se pudo conectar?
$error = $cliente->getError();
if ($error) {
echo '<pre style="color: red">' . $error  . '</pre>';
echo '<p style="color:red;'>htmlspecialchars($cliente->getDebug(), ENT_QUOTES).'</p>';
die();
}

// 1. Llamar a la funcion getRespuesta del servidor
$result = $cliente->call(
"$metodoALlamar", // Funcion a llamar
array('parametro' => 'Orlando'), // Parametros pasados a la funcion
"uri:$serverURL/$serverScript", // namespace
"uri:$serverURL/$serverScript/$metodoALlamar" // SOAPAction
);
// Verificacion que los parametros estan ok, y si lo estan. mostrar rta.
if ($cliente->fault) {
echo '<b>Error: ';
print_r($result);
echo '</b>';
} else {
$error = $cliente->getError();
if ($error) {
echo '<b style="color: red">Error: ' . $error . '</b>';
} else {
echo 'Respuesta: '.$result;
}
}

?>


Primero voy a hacer un breve
resumen de cuales son los pasos que se realizan.

  • Incluír la biblioteca de NuSOAP de PHP.
  • Defino las variables de configuración (lo hice de esta forma para que les sea más sencillo el definir los parámetros para sus propios servicios web).
  • Creo el objeto NuSOAP Cliente (nusoap_client).
  • Verifico que la conexión se haya podido realizar.
  • Llamó al servicio web del servidor (función getRespuesta definida en las variables de configuración).
  • Verifico que la llamada haya sido exitosa, en caso de ser exitosa muestro la respuesta del servidor, y en caso de error, muestro el mensaje de error.
El código del cliente también esta comentado, y definí 3 variables al principio que nos permitirán adaptar el cliente del WebService a nuestras pruebas particulares.
En el cliente no hago un procesamiento de la información recibida desde el servidor de WebServices (NuSOAP server) sino que la muestro directamente por pantalla, cuando estemos trabajando realmente con dicha información debemos realizar un procesamiento de la información recibida antes de utilizarla (el procesamiento puede ser desde algo tan sencillo como mostrar la información en un sitio especifico del website, hasta generar tablas o campos de edición). Las posibilidades de procesamiento son infinitas, y dependen de para que estemos utilizando el WebService, y la información otorgada por el mismo.

Verificación de los scripts

Para comprobar que nuestros scripts estan funcionando, lo que primero recomiendo es primero acceder al script del servidor (http://<direccion de nuestro server>/nusoap_server_ej1.php) desde nuestro navegador, el cual nos debe mostrar una pantalla similar a la siguiente si todo esta correcto (en caso contrario mostrará un típico error PHP por pantalla):

Y si hacemos click sobre el nombre la la función que hemos publicado en nuestro servidor de WebService, nos mostrará algo similar a esto:

Cuando hemos verificado que el servidor esta funcionando, ahora realizaremos la prueba del cliente (http://<direccion de nuestro server>/nusoap_client_ej1.php), y nos mostrará una página similar a la siguiente:

Conclusión

El WebService aquí presentado es un ejemplo básico para todas aquellas personas que estan comenzando con ellos y desean utilizar NuSOAP para crear los mismos y consumirlos.  El código del ejemplo es muy sencillo, pero igualmente decidí publicar un archivo con el ejemplo del cilente y el servidor, para que sea más sencilla la implementación del ejemplo en sus computadoras (Descargar el ejemplo).