44
Servicios Web http://www.orlandobrea.com.ar/search/label/webservices Servicios Web – Retornar un XML con NuSOAP Aquí estoy nuevamente con un artículo de web services / servicios web, en esta oportunidad, voy a incluir un ejemplo en el cual ser servidor retorna un XML al cliente, y este lo muestra por pantalla. Este ejemplo surgió a petición de un visitante a mi blog. Espero que les sea de utilidad. Servidor El servidor es muy similar a todos los servidores de los ejemplos anteriores, simplemente que retorna un XML. Dado que el servidor retorna un XML, debemos convertirlo antes de poder retornarlo, para que no genere conflictos con el código del “envoltorio” (SOAP) que transportará el XML. La forma más rápida es utilizar el método base64_encode que ya trae incorporado PHP. Es decir, codificamos el XML con base64, de esta forma nos aseguramos que no aparecerán caracteres extraños, y luego retornamos ese XML modificado. <?php require_once('nusoap/lib/nusoap.php'); $miURL = 'http://pruebas.orlandobrea.com.ar/nusoap_ejXML'; $server = new soap_server(); $server->configureWSDL('ws_orlando', $miURL); $server->wsdl->schemaTargetNamespace=$miURL; $server->register('getXML', // Nombre de la funcion array(), // Parametros de entrada array('return' => 'xsd:string'), // Parametros de salida

Servicios Web

Embed Size (px)

Citation preview

Page 1: Servicios Web

Servicios Web

http://www.orlandobrea.com.ar/search/label/webservices

Servicios Web – Retornar un XML con NuSOAP

Aquí estoy nuevamente con un artículo de web services / servicios web, en esta oportunidad, voy a incluir un ejemplo en el cual ser servidor retorna un XML al cliente, y este lo muestra por pantalla. Este ejemplo surgió a petición de un visitante a mi blog. Espero que les sea de utilidad.

Servidor

El servidor es muy similar a todos los servidores de los ejemplos anteriores, simplemente que retorna un XML. Dado que el servidor retorna un XML, debemos convertirlo antes de poder retornarlo, para que no genere conflictos con el código del “envoltorio” (SOAP) que transportará el XML. La forma más rápida es utilizar el método base64_encode que ya trae incorporado PHP. Es decir, codificamos el XML con base64, de esta forma nos aseguramos que no aparecerán caracteres extraños, y luego retornamos ese XML modificado.

<?php require_once('nusoap/lib/nusoap.php'); $miURL = 'http://pruebas.orlandobrea.com.ar/nusoap_ejXML'; $server = new soap_server(); $server->configureWSDL('ws_orlando', $miURL); $server->wsdl->schemaTargetNamespace=$miURL;

$server->register('getXML', // Nombre de la funcion                    array(), // Parametros de entrada                    array('return' => 'xsd:string'), // Parametros de salida                    $miURL); function getXML(){     return new soapval('return', 'xsd:string', base64_encode('<?xml version="1.0" encoding="UTF-8"?> <vehiculos>   <coche>       <marca>Toyota</marca>       <modelo>Corolla</modelo>       <fechaCompra>2002</fechaCompra> 

Page 2: Servicios Web

  </coche>   <coche>       <marca>Honda</marca>       <modelo>Civic</modelo>       <fechaCompra>2003</fechaCompra>   </coche')); }

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

En el ejemplo el XML es fijo y esta incorporado a la función del web services, en la vida real, el código XML lo generaremos a partir de algunos datos dinámicos o en como necesitemos.

Cliente

El cliente es casi el mismo que en los ejemplos iniciales que he dado en mi blog, salvo que antes de mostrar/procesar la respuesta, se debe transformar de base64 a texto normal, algo así como “descodificarla”. Para esto PHP también nos provee de una función base64_decode.

<?php require_once('nusoap/lib/nusoap.php'); // Crear un cliente apuntando al script del servidor (Creado con WSDL) $serverURL = 'http://pruebas.orlandobrea.com.ar'; $serverScript = 'nusoap_server_ejXML.php'; $metodoALlamar = 'getXML';

$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(); }

Page 3: Servicios Web

// 1. Llamar a la funcion getRespuesta del servidor $result = $cliente->call(     "$metodoALlamar",                     // Funcion a llamar     array(),    // 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 base64_decode($result);

    } }

?>

En el ejemplo, solo muestro la respuesta que me ofreció el servidor del servicio web, cuando estemos ante una implementación real, seguramente deberemos procesar esta información para ofrecer, por ejemplo, una respuesta a un usuario.

Conclusión

Como hemos podido ver, la implementación de este tipo de alternativas, es muy sencilla, solo debemos tener especial cuidado en la codificación de la respuesta que utilizamos en NuSOAP. A modo de “regla” podría decir que todo aquello que sabemos que utilizará caracteres extraños, podemos codificarlo en base 64 en el servidor, y luego decodificarlo en el cliente (de esta forma nos aseguramos que la información ha viajado correctamente).

Page 4: Servicios Web

Debo reconocer que hace tiempo que no indago el código de NuSOAP, por lo tanto no recuerdo si codifica de alguna forma las respuestas automáticamente (que yo recuerde, no lo hace).

Espero que haya sido de utilidad, y que sirva para que sigan explorando con los Web Services.

Saludos a todos los seguidores, y gracias!

Publicadas por Orlando a las 00:36 4 comentarios 

Etiquetas: desarrollo, tecnologia, webservices

03/05/2010WebServices con NuSOAP en PHP - Ejemplo 4 - VistaBueno, estoy volviendo al blog de a poco, es por eso que estoy publicando la 4 parte de los ejemplos de web services con NuSOAP. En esta oportunidad voy a poner un simple ejemplo de cliente/servidor en el cual el cliente muestra la información enviada por el servidor. 

Si bien el código es muy sencillo, y parecido a los ejemplos anteriores, puede ser un poco más complejo de seguir, ya que hay una parte de visualización de los datos obtenidos desde el servidor (a diferencia de los ejemplos anteriores). 

Es importante aclarar que esta forma de desarrollo no es la más aconsejable para un desarrollo real, ya que la vista esta muy ligada al código de conexión. Todo mejoraría un poco más utilizando algún sistema de templates, como smarty, twig, etc. 

¿Como funciona el ejemplo? 

El cliente llama a listarClientes en el servidor, y muestra el resultado retornado en una tabla. Cuando el usuario hace click para ver los datos de un determinado cliente, el cliente (PHP) llama a getCliente, que retorna todos los datos del cliente. Luego, muestra todos los datos obtenidos del servidor al usuario. 

Comencemos por el servidor 

Page 5: Servicios Web

<?php 

require_once('nusoap/lib/nusoap.php'); require_once('cliente.php'); require_once('clienteDAO.php'); require_once('soporte_obrea.php');

$miURL = 'http://pruebas.orlandobrea.com.ar/nusoap'; $server = new soap_server(); $server->configureWSDL('ws_orlando', $miURL); $server->wsdl->schemaTargetNamespace=$miURL;

$soporteWS = new SoporteWS(); // Creo una instancia del objeto propio (SoporteWS)

// ---------------- Funciones usadas por el WS function getCliente($id) {     global $soporteWS;     $dao = new ClienteDAO();     $cliente = $dao->getCliente($id);     $respuesta = $soporteWS->convertirAVectorParaWS($cliente);     return new soapval('return', 'tns:Cliente', $respuesta); } function listarClientes() {     $dao = new ClienteDAO();     $listado = $dao->getList();     $objSoporte = new SoporteWS();     $respuesta = $objSoporte->convertirAVectorParaWS($listado);                      return new soapval('return', 'tns:listadoClientes', $respuesta);}

// --------------- Definicion de las funciones y estructuras expuestas en el WS $server->wsdl->addComplexType('Cliente',     'complexType',     'struct',     'all',     '',     array(         'id' => array('name' => 'id', 'type' => 'xsd:int'),         'nombre' => array('name' => 'nombre',    'type' =>

Page 6: Servicios Web

'xsd:string'),         'apellido' => array('name' => 'apellido', 'type' => 'xsd:string'),         'cuit' => array('name' => 'CUIT',    'type' => 'xsd:string')     ) ); $server->wsdl->addComplexType('listadoClientes',     'complexType',     'array',     '',     '',     array (array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:Cliente[]')) );

$server->register('getCliente', // Nombre de la funcion                    array('id' => 'xsd:int'), // Parametros de entrada                    array('return' => 'tns:Cliente'), // Parametros de salida                    $miURL                  ); $server->register('listarClientes', // Nombre de la funcion                    array(), // Parametros de entrada                    array('return' => 'tns:listadoClientes'), // Parametros de salida                    $miURL                  );

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

El servidor es muy similar a los anteriores, expone solo dos métodos: 

listarClientes: retorna una lista con los clientes. getCliente: retorna el cliente cuyo id es recibido como

parámetro de llamada.

La definición del objeto, y los métodos de acceso a datos (DAO) están definidos en los archivos que son importados (cliente.php y clienteDAO.php). Recomiendo que te descargues el archivo comprimido con todo los archivos, que se encuentra al final de este tutorial y que prestes atención a estos archivos. Si bien son muy sencillos, te ayudará mucho que vayas realizando pruebas sobre los

Page 7: Servicios Web

mismos también para que puedas ver el comportamiento. Si solo te interesa la parte de WS (Web Services), puedes prestar atención solo a los archivos que están publicados.

¿Como es el cliente?Bueno, el cliente es un poquito más complejo que los anteriores, ya que no solo hace peticiones al servidor, sino que tiene una pequeña interacción y presenta los datos al usuario.

<?php require_once('nusoap/lib/nusoap.php'); require_once('cliente.php'); require_once('soporte_obrea.php');

// Crear un cliente apuntando al script del servidor (Creado con WSDL) $serverURL = 'http://pruebas.orlandobrea.com.ar'; // Reemplazar por la URL de tu servidor $serverScript = 'nusoap_server_ej4_view.php'; $soporteWS = new SoporteWS();

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

$listado = ''; $objCliente = ''; // Existe el parametro "view" en la URL con la cual se esta llamando a este script? if ($_GET['view']) { 

Page 8: Servicios Web

    // Si => debo mostrar los datos del cliente     $metodoALlamar = 'getCliente';     $result = $cliente->call(         $metodoALlamar,                     // Funcion a llamar         array($_GET['id']),    // 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 {             $objCliente = $soporteWS->convertirDeVectorDesdeWS($result, 'Cliente');          }     } } else { // No fue llamado con el parametro "view" en la URL => debo mostrar el listado de clientes     $metodoALlamar = 'listarClientes';     $result = $cliente->call(         $metodoALlamar,                     // Funcion a llamar         array(),    // 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 { 

Page 9: Servicios Web

        $error = $cliente->getError();         if ($error) {             echo '<b style="color: red">Error: ' . $error . '</b>';         } else {             $listado = $soporteWS->convertirDeVectorDesdeWS($result, 'Cliente');          }     } } // De aca en mas es la pagina HTML que muestra el listado de clientes o los datos de un cliente en particular (dependiendo // si se llamo con view como parametro o no) ?> <html> <body>     <? if ($listado) { ?>     <!-- Listado de todos los clientes -->     <h1>Listado</h1>     <table>         <tr><td>Nombre</td><td>Apellido</td><td>CUIT</td><td>Acciones</td></tr>         <?php             foreach ($listado as $objeto) {                 echo '<tr>';                 echo '<td>'.$objeto->nombre.'</td>';                 echo '<td>'.$objeto->apellido.'</td>';                 echo '<td>'.$objeto->cuit.'</td>';                 echo '<td><a href="nusoap_client_ej4_view.php?view=yes&id='.$objeto->id.'">Ver</a></td>';                 echo '</tr>';             }         ?>     </table>     <? } else { ?>     <!-- Datos del cliente seleccionao -->     <h1>Cliente</h1>     <?php         echo '<strong>ID:</strong> '.$objCliente->id.'<br/>';         echo '<strong>Nombre:</strong> '.$objCliente->nombre.'<br/>'; 

Page 10: Servicios Web

        echo '<strong>Apellido:</strong> '.$objCliente->apellido.'<br/>';         echo '<strong>CUIT:</strong> '.$objCliente->cuit.'<br/>';    ?>     <? } ?> </body> </html>

Como mencione anteriormente, el cliente es un poco más complejo que los anteriores, ya que el mismo script permite ver el listado de clientes, y los datos de un cliente en particular. Si el script, no recibe parámetros en la URL, muestra el listado de todos los clientes que se encuentran en el sistema (llamando a listarClientes en el WS). En cambio si recibe el parámetro view, y el id del cliente que se desea mostrar, ejecuta otra sección del script, la que muestra los datos del cliente. 

La página del listado se ve así 

Y luego de hacer click sobre "Ver", nos lleva a la página: 

Page 11: Servicios Web

la cual contiene el detalle del cliente seleccionado, en este caso "Blas Pascal". Ambas páginas, se encuentran en el mismo script. Es cuestión de gustos incluir ambas en el mismo script, o utilizar dos scripts diferentes. A los fines de este artículo, me pareció más práctico incluir toda la información del cliente en un único script. Si lo deseas, puedes separar el archivo cliente en dos scripts menores. 

Los archivos cliente, y servidor los puedes descargar aquí 

Conclusión 

Este artículo, es una recopilación de los anteriores, con unos pequeños agregados, como la interacción con el usuario, y la presentación de la información. 

Este artículo pretende ser el puntapié inicial para que comiences a explorar tu mismo con los servicios web, ya sean en PHP o cualquier otro lenguaje que te guste. Las posibilidades son infinitas, tu serás el que ponga los limites en que aplicación o módulo utilizarás web services. Ya tienes una base para seguir explorando, ahora depende mucho de ti que practiques y comiences a utilizarlos en tus proyectos. 

Page 12: Servicios Web

Debo hacer una aclaración que creo que es importante si aún no has comenzado proyectos con Web services. Al comenzar a utilizar web services, te encontrarás con varios inconvenientes, algunos de la herramienta que utilizamos, y otros propios de la etapa de aprendizaje. Lo importante es saber que el camino puede ser un poco difícil en algunos momentos, pero se puede lograr. Si te quedas atascado, sigue probando, descansa un poco, piensa alternativas, busca las posibles causas, y vuelve a retomar. Por eso es tan importante, que no comiences con un proyecto real, sino que, como todo, comiences sobre un proyecto interno, o de prueba, para ir probando y tener tiempo para encontrar los trucos.

Otro punto importante, los Web Services, tampoco son la bala de plata (Silver bullet), por lo tanto, no intentes utilizarlos para cualquier proyecto, aplica tu criterio para decidir que es lo más conveniente para cada proyecto o módulo que debes realizar. 

Espero que haya sido de utilidad, me gustaría conocer tu experiencia, si te ha resultado de utilidad este artículo, y que información más te gustaría encontrar sobre estos temas. 

Éxitos y a seguir probando.

Publicadas por Orlando a las 22:22 6 comentarios 

Etiquetas: desarrollo, tecnologia, webservices

01/12/2009Como transferir archivos con NuSOAPGracias al comentario de un visitante a mi blog, me dí cuenta que no había incluído ejemplos de como transferir archivos mediante un servicio web, más precisamente utilizando NuSOAP.

Por lo tanto hoy realice un ejemplo muy sencillo que nos permite hacer precisamente eso, tener un servidor corriendo NuSOAP, y que un cliente realice una petición y el servidor retorne el archivo solicitado por el cliente.

Servidor para transferir archivosEl servidor es muy similar al ejemplo que utilice en el primer post que realice en mi blog sobre este tema (http://www.orlandobrea.com.ar/2009/09/webservices-con-nusoap-en-

Page 13: Servicios Web

php-ejemplo-1.html). Voy a ir directamente al ejemplo, ya que todo lo necesario para entender el mismo ya lo he explicado en los posts anteriores.

// Archivo nusoap_server_ejFile.php

<?php

require_once('nusoap/lib/nusoap.php');

$miURL = 'http://pruebas.orlandobrea.com.ar/nusoap_ej1';

$server = new soap_server();

$server->configureWSDL('ws_orlando', $miURL);

$server->wsdl->schemaTargetNamespace=$miURL;

$server->register('getArchivo', // Nombre de la funcion

array('nombre' => 'xsd:string'), // Parametros de entrada

array('return' => 'xsd:string'), // Parametros de salida

$miURL);

// Función que recibe el nombre del archivo que debe retornar.

// Lee el contenido del archivo cuyo nombre corresponde con el pasado

// como parámetro a la función, le aplica Base64 para codificar su

// contenido, y luego lo retorna como un string

function getArchivo($nombre){

$archivo = file_get_contents($nombre);

$archivo = base64_encode($archivo);

return new soapval('return', 'xsd:string', $archivo);

}

$server->service($HTTP_RAW_POST_DATA);

?>

El cliente que recibe los archivosEl cliente también es muy similar al del primer ejemplo, por lo tanto ya vamos a lo importante, el código.

// Archivo nusoap_client_ejFile.php

<?php

require_once('nusoap/lib/nusoap.php');

// Crear un cliente apuntando al script del servidor (Creado con WSDL)

$serverURL = 'http://pruebas.orlandobrea.com.ar';

Page 14: Servicios Web

$serverScript = 'nusoap_server_ejFile.php';

$metodoALlamar = 'getArchivo';

$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 getArchivo del servidor, pasando como parámetro

'wallpaper_mac.png'

$result = $cliente->call(

"$metodoALlamar", // Funcion a llamar

array('wallpaper_mac.png'), // 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 {

// Decodificación de la respuesta del servidor

$contenido = base64_decode($result);

// Guardar la respuesta del servidor, decodificada, en el archivo

tmp.png

file_put_contents("tmp.png", $contenido);

}

}

?>

Page 15: Servicios Web

El código es bastante sencillo de enteder, simplemente se llama a getArchivo en el webservice del servidor, y se le pasa como parámetro el archivo que deseamos descargar (en este caso wallpaper_mac.png). El servidor retorna el archivo al cliente (codificado con base64). El cliente recibe el archivo y lo decodifica, luego lo guarda en un archivo "tmp.png".El ejemplo es muy sencillo, y no es apto para un ambiente productivo. Para poder usar este ejemplo en un servidor productivo, deberíamos:

Agregar verificación de errores (Por ejemplo, que el archivo exista).

El servidor debe establecer ciertas reglas de seguridad (Por ejemplo que solo se pueda acceder a ciertos archivos)

Que el cliente pueda solicitar diferentes tipos de archivos (que el archivo a solicitar no este fijo como en el ejemplo, wallpaper_mac.png).

Que el archivo en el cual se guarda el archivo recibido, sea modificable.

Estos son solo algunas correcciones que deberíamos hacer para mejorar el código y que sea más seguro. Para los fines del ejemplo, preferí mantener el mismo lo más sencillo posible, para enfocarnos en lo importante en este caso.Este ejemplo también esta disponible para su descarga.

Publicadas por Orlando a las 22:48 2 comentarios 

Etiquetas: tecnologia, webservices

11/11/2009WebServices con NuSOAP en PHP - Ejemplo 3Este el tercer ejemplo que voy a publicar de la comunicación entre el cliente y servidor de WebServices utilizando NuSOAP con un servidor PHP. Para aquellos que llegarón directamente a esta página, les recomiendo que primero lean el primer ejemplo de NuSOAP con PHP, y luego el segundo ejemplo de NuSOAP con PHP, antes de continuar con este. En este ejemplo en particular voy a modificar el ejemplo 2, para en vez de retornar un objeto, retornar una lista de objetos. En el ejemplo anterior, trate un caso muy particular, que es cuando necesitamos obtener un objeto desde el servidor, en este nuevo ejemplo, voy a obtener un listado de objetos. Muchas veces necesitamos un listado de algún tipo de objeto, por ejemplo, un

Page 16: Servicios Web

listado de clientes, con este nuevo Servicio Web planteo este caso, en el cual el servidor nos devuelve un listado con todos los clientes que existen en el sistema.Como veremos existen algunas modificaciones extras que debemos realizar para retornar un listado con los clientes. Primero debemos definir una estructura que contenga a la definición planteada en el ejemplo anterior, y luego realizar una conversión un poco más compleja (de un vector de objetos, a un vector de vector). También voy a incluír una clase de soporte, que nos ayudará a realizar las conversiones.

Módulo ServidorPara simplificar la estructura del servidor, intente extraer toda la lógica de conversión en una clase extra (smart_soporte.php), así la lectura del código del servidor se mantiene lo suficientemente limpia como para que sea más fácil su entendimiento. En elejemplo anterior el servicio web retornaba un cliente al consumidor/cliente de dicho servicio web, en este caso, retornaremos un listado de clientes. Debemos tener en cuenta que las respuestas deben ser convertidas a los tipos de datos básicos, por lo tanto para devolver una lista de clientes, debemos convertir dicha lista en un lista de listas que contengan como indices/keys/claves los atributos de la clase Cliente.A continuación expongo el código del servidor: 

<?php

// Pull in the NuSOAP code

require_once('nusoap/lib/nusoap.php');

require_once('soporte_obrea.php'); // Incluyo este archivo que tiene

archivos para soporte de WS

$miURL = 'http://pruebas.orlandobrea.com.ar/nusoap';

$server = new soap_server();

$server->configureWSDL('ws_orlando', $miURL);

$server->wsdl->schemaTargetNamespace=$miURL;

/*

* Ejemplo 3: listarClientes es la funcion mas compleja que voy

realizar, no recibe parametros

Page 17: Servicios Web

* y retorna un listado de clientes. Utiliza varios metodos del ejemplo

2.

*/

class Cliente {

var $id;

var $nombre;

var $apellido;

var $cuit;

}

class ClienteDAO {

/**

* getCliente($id) : Cliente

* Esta funcion deberia implementarse con una conexion a una base de

datos

* y obtener la informacion de la base directamente

*/

function getCliente($id) {

$obj = new Cliente();

if ($id==1) {

$obj->id = 1;

$obj->nombre = 'Blas';

$obj->apellido = 'Pascal';

$obj->cuit = '11-11111111-1';

}

if ($id==2) {

$obj->id = 2;

$obj->nombre = 'Isaac';

$obj->apellido = 'Newton';

$obj->cuit = '22-22222222-2';

}

return $obj;

}

/**

* getList : Array

* Esta funcion retorna un listado de todos los clientes que estan en el

sistema.

* @return

*/

function getList() {

$rta = array();

Page 18: Servicios Web

$rta[0] = $this->getCliente(1);

$rta[1] = $this->getCliente(2);

return $rta;

}

}

$server->wsdl->addComplexType('Cliente',

'complexType',

'struct',

'all',

'',

array(

'id' => array('name' => 'id', 'type' => 'xsd:int'),

'nombre' => array('name' => 'nombre', 'type' => 'xsd:string'),

'apellido' => array('name' => 'apellido', 'type' => 'xsd:string'),

'cuit' => array('name' => 'CUIT', 'type' => 'xsd:string')

)

);

$server->wsdl->addComplexType('listadoClientes',

'complexType',

'array',

'',

'',

array (array('ref'=>'SOAP-

ENC:arrayType','wsdl:arrayType'=>'tns:Cliente[]'))

);

$server->register('listarClientes', // Nombre de la funcion

array(), // Parametros de entrada

array('return' => 'tns:listadoClientes'), // Parametros de salida

$miURL

);

function listarClientes() {

$dao = new ClienteDAO();

$listado = $dao->getList();

$objSoporte = new SoporteWS();

$respuesta = $objSoporte->convertirAVectorParaWS($listado);

return new soapval('return', 'tns:listadoClientes', $respuesta);

}

Page 19: Servicios Web

$server->service($HTTP_RAW_POST_DATA);

?>

Existen una lista de modificaciones que voy a ir detallando en los siguientes puntos.Agregar una función en el DAO para que retorne una listaComo mencione anteriormente en esta oportunidad debemos retornar un listado de clientes, por eso debemos modificar la clase ClienteDAO agregando un nuevo método getList, el cual retorna una lista con todos los clientes. 

function getList() {

$rta = array();

$rta[0] = $this->getCliente(1);

$rta[1] = $this->getCliente(2);

return $rta;

}

La clase ObjetoDAO agrega un nuevo método llamado getList(), el cual retorna una lista de todos los clientes que tenemos en el sistema. Al igual que en el ejemplo 2, cuando implementemos este método en un servidor productivo, tendrá una lógica de acceso a datos para obtener la información de alguna fuente de datos. Por ejemplo, si la fuente de datos fuera una base de datos, deberiamos ejecutar una sentencia SQL similar a "select * from Cliente" y luego convertir los resultados en un listado de Clientes.Definimos la estructura retornadaDebemos definir el nuevo tipo de datos que vamos a retornar, en este caso debemos retornar una lista de clientes, la cual esta definida por la siguiente estructura:

$server->wsdl->addComplexType('listadoClientes',

'complexType',

'array',

'',

'',

array (array('ref'=>'SOAP-

ENC:arrayType','wsdl:arrayType'=>'tns:Cliente[]'))

);

Como podemos ver en el código anterior, definimos un tipo de datos "listadoClientes" el cual es un array de "Cliente" (el tipo de datos que

Page 20: Servicios Web

habíamos definido en el ejemplo 2). Con estas simples lineas estamos indicando que vamos a retornar un listado (vector) y que cada elemento de dicho vector contendrá un Cliente.Registramos el servicio web a publicar

$server->register('listarClientes', // Nombre de la funcion

array(), // Parametros de entrada

array('return' => 'tns:listadoClientes'), // Parametros de salida

$miURL

);

Al igual que en los ejemplos anteriores debemos registrar/publiar el servicio web, para ello llamamos a el método register del server. Definimos que el servicio web expuesto llamará a la función "listarClientes" y que la misma retornará un tipo de datos tns:listadoClientes (el tipo de datos definido en el punto anterior).Implementación de la funciónDebemos implementar la función que será llamada cuando el cliente del webservice haga uso del mismo. En este caso será implementado por la función listarClientes().

function listarClientes() {

$dao = new ClienteDAO();

$listado = $dao->getList();

$objSoporte = new SoporteWS();

$respuesta = $objSoporte->convertirAVectorParaWS($listado);

return new soapval('return', 'tns:listadoClientes', $respuesta);

}

Esta función es muy similar a la del ejemplo 2, pero en este caso hacemos uso de un objeto auxiliar (que he creado y el código del mismo esta disponible para descargar al final del artículo) el cual se encarga de la conversión del vector de objetos, en un vector de vector. La conversión es realizada por el método convertirAVectorParaWS del objeto $objSoporte (el cual es de la clase SoporteWS). Al igual que en los ejemplos anteriores, debemos convertir la respuesta en un tipo de datos predefinido, en este caso es el que creamos recientemente (tns:listadoClientes).Como se puede ver, una vez pasado el ejemplo 1, los pasos son más repetitivos, hemos incorporado algunos objetos de soporte para mantener el código limpio, e intentado hacer el ejemplo cada vez un poco más cercano al mundo real.  

Módulo Cliente

Page 21: Servicios Web

El módulo cliente es el mismo que el del ejemplo 2, simplemente modificamos el nombre del script del servidor y el nombre de la función a llamar. En este caso el script del servidor tiene como nombre "nusoap_server_ej3.php" y la función que vamos a hacer uso en el webservice es "listarClientes"

<?php

require_once('nusoap/lib/nusoap.php');

// Crear un cliente apuntando al script del servidor (Creado con WSDL)

$serverURL = 'http://pruebas.orlandobrea.com.ar';

$serverScript = 'nusoap_server_ej3.php';

$metodoALlamar = 'listarClientes';

$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();

}

// 2. Llamar a la funcion listadoClientes del servidor

$result = $cliente->call(

$metodoALlamar, // Funcion a llamar

array(), // 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 {

Page 22: Servicios Web

echo 'Respuesta: ';

print_r($result);

}

}

?>

ConclusiónUna vez que vamos avanzando en los ejemplos de WebServices podemos ver la complejidad de los mismos se puede mantener en un nivel similar (ayudandonos de algunos objetos de soporte). Como ya se habrán dado cuenta, no voy a describir la implementación de la clase SoporteWS ya que el código de la misma es código PHP standard, y escapa a los fines del ejemplo. Para simplificar lo que hace esta clase es convertir un objeto en un vector, y un listado de objetos, en un vector de vector. En el próximo ejemplo voy a hacer un ejemplo del mundo real, en el cual se listan los usuarios y al hacer click sobre un enlace, podemos ver todos los datos del mismo. El código de este ejemplo se puede descargar aquí.Espero que los ejemplos hayan podido introducir a todas aquellas personas que estan realizando webservices, o estan planeando realizar webservices con PHP y NuSOAP.   

AGREGADO: Enlace para descargar el ejemplo completo

Publicadas por Orlando a las 21:21 12 comentarios 

Etiquetas: desarrollo, tecnologia, webservices

26/09/2009WebServices con NuSOAP en PHP - Ejemplo 2

En este segundo ejemplo de WebServices con PHP utilizando NuSOAP como biblioteca, voy a mostrar un ejemplo un poco más complejo que el del post anterior (WebServices con NuSOAP en PHP - Ejemplo 1). En este nuevo ejemplo voy a añadir un objeto "Cliente" en el servidor, el cual va a ser devuelto al consumidor/cliente del webservice (previa conversión del objeto a un vector). Para que quede más en claro, comenzare por los ejemplos del servidor y el cliente.

El servidor

Page 23: Servicios Web

Al ser un ejemplo un poco más complejo decidí agregar algunos comentarios más para que el código sea un poco más legible. Igualmente luego del código comentaré algunos fragmentos de código más en detalle. 

<?php

// Importar la biblioteca NuSOAP

require_once('nusoap/lib/nusoap.php');

$miURL = 'http://pruebas.orlandobrea.com.ar/nusoap';

$server = new soap_server();

$server->configureWSDL('ws_orlando', $miURL);

$server->wsdl->schemaTargetNamespace=$miURL;

/*

* Ejemplo 2: getCliente es una funcion mas compleja que recibe un id y

retorna el cliente

* que le corresponde (solo retorna 2 clientes). Tener en cuenta que las

respuestas del

* WebService son un Array (vector) y no un objeto propiamente dicho. Si

deseamos recuperar

* el objeto del lado del cliente, lo debemos convertir de vector a

objeto. En el ejemplo 3

* se ampliara sobre este tipo de operaciones.

*/

// El objeto que voy a enviar al cliente como respuesta

class Cliente {

var $id;

var $nombre;

var $apellido;

var $cuit;

}

// Un objeto de acceso a datos (DAO - Data Access Object) que es el

encargado de

// administrar los objetos almacenados (en este caso todos los valores

estan

// prefijados, pero en un ejemplo real se podrian obtener de una base de

datos)

class ClienteDAO {

/**

* getCliente($id) : Cliente

Page 24: Servicios Web

* Esta funcion deberia implementarse con una conexion a una base de

datos

* y obtener la informacion de la base directamente

*/

function getCliente($id) {

$obj = new Cliente();

if ($id==1) {

$obj->id = 1;

$obj->nombre = 'Blas';

$obj->apellido = 'Pascal';

$obj->cuit = '11-11111111-1';

}

if ($id==2) {

$obj->id = 1;

$obj->nombre = 'Isaac';

$obj->apellido = 'Newton';

$obj->cuit = '22-22222222-2';

}

return $obj;

}

}

// Creo la estructura en la cual voya convertir al objeto Cliente, para

enviarlo al

// consumidor del WebService (En este caso contiene un vector con id,

nombre, apellido

// y cuit)

$server->wsdl->addComplexType('Cliente',

'complexType',

'struct',

'all',

'',

array(

'id' => array('name' => 'id', 'type' => 'xsd:int'),

'nombre' => array('name' => 'nombre', 'type' => 'xsd:string'),

'apellido' => array('name' => 'apellido', 'type' => 'xsd:string'),

'cuit' => array('name' => 'CUIT', 'type' => 'xsd:string')

)

);

// Registro la funcion que se expone en el webservice, la que puede

consumir el cliente,

// e indico a que funcion PHP se debe llamar cuando el cliente invoque el

Page 25: Servicios Web

webservice

// (getCliente)

$server->register('getCliente', // Nombre de la funcion

array('id' => 'xsd:int'), // Parametros de entrada

array('return' => 'tns:Cliente'), // Parametros de salida

$miURL

);

// Funcion que es llamada por el WebService de NuSOAP cuando el cliente

intenta consumir

// el servicio web expuesto

function getCliente($id) {

$dao = new ClienteDAO();

$cliente = $dao->getCliente($id);

// Convierto el objeto en un vector, con una key por cada propiedad del

objeto

$respuesta = array('id'=> $cliente-id,

'nombre' => $cliente->nombre,

'apellido' => $cliente->apellido,

'cuit' => $cliente->cuit

);

// Indico que el parametro de respuesta es del tipo tns:Cliente, y cual

es el vector

// que contiene dicha estructura

return new soapval('return', 'tns:Cliente', $respuesta);

}

$server->service($HTTP_RAW_POST_DATA);

?>

En el códido de este nuevo ejemplo, existen algunas diferencias con respecto al del ejemplo1, por eso voy a intentar detallar cada una de ellas con un poco de detalle, para poder explicar de que se trata cada una de las nuevas incorporaciones.

Creamos un objeto Cliente

En este nuevo módulo servidor utilizamos una clase llamada "Cliente" que es la que luego de ser convertida, será devuelta al cliente/consumidor del WebService. Decidí crear una clase, para hacer el ejemplo un poco más acorde a lo que nos encontraremos en la vida cotidiana, es decir, hoy en día estamos muy acostumbrados a

Page 26: Servicios Web

trabajar con objetos, y que toda la información que tengamos disponibles en nuestros sistemas se encuentren representadas por objetos. Es por eso, que comence  incorporar los objetos al ejemplo. La definición de la clase es la siguiente:

class Cliente {

var $id;

var $nombre;

var $apellido;

var $cuit;

}

Es un objeto muy simple, el cual no tiene asociaciones con otros objetos, simplemente tiene 4 atributos:

id nombre apellido cuit

Si bien el objeto es muy simple, nos servirá para poder comenzar a ver cuales son las implicancias del mismo y como debemos convertirlo para luego retornarlo el cliente del webservice.

Creamos un objeto ClienteDAO

Siguiendo con la esta nueva meta de acercar el ejemplo a la vida real, incorporé un objeto DAO (Data Access Object). Para aquellos que no conocen o no están acostumbrados a usar un DAO, voy a intentar definirlo con unas pocas palabras. Cuando creamos aplicaciones multicapa, algo muy común hoy en día, es normal que una de las capas se llame DAO, que podríamos traducir como Capa de Acceso a Datos. Esta capa de acceso a datos, es la encargada de manejar los datos de la aplicación, por ejemplo la que se encarga de leer, guardar y borrar datos de un origen de datos, como podría ser una base de datos, un archivo XML, u otro webservice. Esta capa nos permite abstraer toda la lógica de acceso a datos, para que, si el día de mañana decidimos cambiar de motor de base de datos, o de origen de datos, no tengamos que modificar todas las demás partes del código, solamente cambiamos las clases de esta capa. Generalmente se utiliza un objeto DAO por cada objeto del dominio que queremos

Page 27: Servicios Web

guardar/modificar/borrar (existen formas de agrupar en un único objeto las operaciones sobre varios objetos del dominio, pero es dependiente del lenguaje, y prefiero no ahondar en ello para no complicar el ejemplo).

Ya explicado, muy brevemente, que es un DAO vamos a la definición de la clase ClienteDAO:

class ClienteDAO {

/**

* getCliente($id) : Cliente

* Esta funcion deberia implementarse con una conexion a una base de

datos

* y obtener la informacion de la base directamente

*/

public function getCliente($id) {

$obj = new Cliente();

if ($id==1) {

$obj->id = 1;

$obj->nombre = 'Blas';

$obj->apellido = 'Pascal';

$obj->cuit = '11-11111111-1';

}

if ($id==2) {

$obj->id = 1;

$obj->nombre = 'Isaac';

$obj->apellido = 'Newton';

$obj->cuit = '22-22222222-2';

}

return $obj;

}

}

Simplemente definimos un método, getCliente, para el objeto que crearemos. Para mantener el ejemplo sencillo, la información retornada por el mismo esta pre-fijada, es decir, no es tomada desde una base de datos, u otra fuente, como si sería en una aplicación del mundo real. Si este método lo implementaramos en una aplicación real, ejecutariamos una sentencia SQL similar a "select * from Cliente where id=".$id y luego convertiriamos la respuesta en un objeto Cliente que es el que retornamos.

Page 28: Servicios Web

Dado que es un ejemplo sin conexión con un origen de datos, esta simple función puede retornar solo 2 objetos clientes, uno para cuando se le pasa como parámetro 1, y otro para cuando se pasa como parámetro 2. En caso de pasar cualquier otro valor como parámetro la función retornará un objeto Cliente sin inicializar sus atributos.

Definimos el tipo de datos devuelto por el WebService

A diferencia del ejemplo 1, en el cual nuestro WebService solo retornaba un String (xsd:string), en esta oportunidad nuestro WebService, retornará un objeto (representado en un vector). Pero como estamos retornando un valor complejo, es decir, no es un string, o int, u otro tipo que ya este predefinido, debemos definirlo nosotros, para ello usamos el siguiente ceodigo:

En el código, estamos informandole a nuestro objeto $server, que utilizaremos un tipo de datos propio, o tipo complejo (este tipo de datos complejo se reflejará en nuestro WSDL del WebService). Los parámetros que más nos interesan para la función "addComplexType" son el primero, y el último. 

El primer parámetro define cual es el nombre que le asignamos a este tipo de datos complejo, en este caso "Cliente".

El último parámetro define como esta compuesto este tipo de datos complejo. Como podemos ver en el ejemplo, el tipo de datos se define como un array (vector) el cual esta compuesto por varios elementos (id, nombre, apellido, cuit), y cada uno de dichos elementos debe tener un vector que contenga "name" y "type" es decir la definición para cada tipo de datos que compone este tipo complejo. Lo que hacemos, no es más que definir un tipo de datos complejo, compuesto por diferentes tipos de datos simples (con simple, me refiero a aquellos que son los estandares) y/o otros tipos de datos complejos que ya hayan sido definidos. Es similar a la definición de una estructura de datos, u objeto. Debemos tener en cuenta que los tipos de datos simples tienen el prefijo xsd (recordarlo para incorporarlo a cada tipo que estamos definiendo).

Registración de la función a exponer

Page 29: Servicios Web

Al igual que en el ejemplo 1, debemos exponer cuales funciones deseamos publicar en nuestro WebService, para ello llamamos al método "register" de nuestro objeto $server, como podemos ver en el siguiente código:

$server->register('getCliente', // Nombre de la funcion

array('id' => 'xsd:int'), // Parametros de entrada

array('return' => 'tns:Cliente'), // Parametros de salida

$miURL

);

La registración de la función expuesta, es muy similar al ejemplo 1, la única diferencia es que en vez de retornar un tipo de datos xsd:string, retornamos un tipo de datos complejo tns:Cliente. Este tipo de datos, es el que definimos en el punto anterior. Con los últimos 2 puntos le estamos indicando a NuSOAP que vamos a retornar un tipo de datos complejo, el cual tiene la estructura definida en tns:Cliente (estructura definida en el punto anterior). 

Función que retorna el cliente

Al igual que en el ejemplo anterior tenemos una función que es la encargada de procesar el pedido y retornar la respuesta. En este caso dicha función se llama getCliente y es la siguiente:

function getCliente($id) {

$dao = new ClienteDAO();

$cliente = $dao->getCliente($id);

// Convierto el objeto en un vector, con una key por cada propiedad del

objeto

$respuesta = array(

'id'=> $cliente->id,

'nombre' => $cliente->nombre,

'apellido' => $cliente->apellido,

'cuit' => $cliente->cuit

);

// Indico que el parametro de respuesta es del tipo tns:Cliente, y cual

es el vector

// que contiene dicha estructura

Page 30: Servicios Web

return new soapval('return', 'tns:Cliente', $respuesta);

}

Al estar utilizando objetos para obtener los datos que deseamos retornar, tenemos algunos pasos más en al función que en el ejemplo anterior. 

Definimos en objeto $dato que es del tipo ClienteDAO (la capa de acceso a datos).

Obtenemos el cliente con el $id pasado como parámetro, a través del objeto DAO que creamos en el primer paso.

Convertimos el objeto cliente en un vector para luego poder retornarlo (usamos como key, el nombre de cada uno de los atributos del objeto).

Retornamos el vector, informando que el mismo es del tipo tns:Cliente (es decir, le pedimos a NuSOAP que nos cree un tns:Cliente a partir del vector pasado como parámetro.

¿Como creo el mapeo entre el objeto y el vector?

Para alcanzar este objetivo, cada uno puede tener sus preferencias, yo utilizó una correspondencia 1 a 1, entre el nombre del atributo y la key del vector. Ejemplo:

class Cliente { $vector = array(

var $id; --------> 'id' => '',

var $nombre; --------> 'nombre' => '',

var $cuit; --------> 'cuit' => ''

} );

Como vemos en el ejemplo, la propiedad id del objeto Cliente, se corresponde con la key 'id' del vector $vector. Cuando el objeto es copiado al vector, al acceder a $cliente->id; PHP no da el mismo valor que $vector['id'];

Cliente

El cliente no tiene mayores modificaciones que el del ejemplo 1, simplemente modifica el nombre del script del servidor, y la función a la cual se llama en el mismo.

Page 31: Servicios Web

<?php

require_once('nusoap/lib/nusoap.php');

// Crear un cliente apuntando al script del servidor (Creado con WSDL)

$serverURL = 'http://pruebas.orlandobrea.com.ar';

$serverScript = 'nusoap_server_ej2.php';

$metodoALlamar = 'getCliente';

$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();

}

// 2. Llamar a la funcion getCliente del servidor

$result = $cliente->call(

"$metodoALlamar", // Funcion a llamar

array('id' => '1'), // 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: ';

print_r($result);

}

}

?>

Page 32: Servicios Web

El cliente es muy sencillo, ya que simplemente muestra el contenido de la respuesta del servidor. En un ejemplo del mundo real, el vector que nos devuelve el servidor, lo deberíamos convertir a un objeto cliente (haciendo el mapeo inverso. Antes pasamos del objeto a un vector, y ahora deberíamos pasar del vector a un objeto). En el ejemplo 4, voy a hacer el cliente un poco más complejo, convirtiendo del vector a un objeto, y luego operando con el objeto.

Conclusión

En este ejemplo el servidor fué el que recibió modificaciones, para poder comenzar a operar con objetos, pero el cliente lo mantuve igual de simple que en el ejemplo anterior. También podésdescargar el archivo comprimido con el ejemplo. Como vemos a medida que vamos aproximando nuestro ejemplo a la vida real, el mismo se hace un poco más complejo y debemos utilizar diferentes conocimientos que a veces escapan al del WebService en si. 

Publicadas por Orlando a las 12:03 10 comentarios 

Etiquetas: desarrollo, tecnologia, webservices

06/09/2009WebServices 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.

Page 33: Servicios Web

Introducción al ejemploNo 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 mismoPara 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.

RequerimientosLos 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 descargarXAMPP 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 servidorEl 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();

Page 34: Servicios Web

$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

Page 35: Servicios Web

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(){

Page 36: Servicios Web

El clientePara 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.

Page 37: Servicios Web

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

Page 38: Servicios Web

que estemos utilizando el WebService, y la información otorgada por el mismo.

Verificación de los scriptsPara 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ónEl 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).

Publicadas por Orlando a las 16:12 35 comentarios 

Etiquetas: desarrollo, tecnologia, webservices