ManuelRomero/DAW/dwes/serviciosWebSoap
De WikiEducator
Revisión a fecha de 01:05 13 mar 2014; ManuelRomero (Discusión | contribuciones)
Contenido
Práctica de servicos web con SOAP
- A partir de la descripción de la práctica.
- Tenemos una serie de métodos o funciones que queremos ofrecer a otras aplicacones web.
Fichero del servicio web
- server.php: en él temenos los métodos que qeremos ofrecer.
- La clase DB.PHP contiene la parte del modelo de datos (conexión a bd, y métodos para recuperar información concreta.
- La clase producto.php tiene los atributos del producto y sus métodos get and set.
<?php require_once('DB.php'); require_once('producto.php'); class Server { /** * Obtiene el PVP de un producto a partir de su código * */ public function getPVP($codigo){ $producto = DB::obtieneProducto($codigo); return $producto->getPVP(); } /** * Devuelve un array con los códigos de todas las familias * */ public function getFamilias(){ $familias = DB::obtieneFamilias(); return $familias; } /** * Devuelve un array con los códigos de los productos de una familia * */ public function getProductosFamilia($familia){ $productos = DB::obtieneProductosFamilia($familia); return $productos; } /** * Devuelve el número de unidades que existen en una tienda de un producto * */ public function getStock($codigo, $tienda){ $unidades = DB::obtieneStock($codigo, $tienda); return $unidades; } } ?>
- Lo que queremos es ofrecer estos métodos para que otras aplicaciones las usen
- Si tenemos la situación que conocemos perfectamente estos métodos, no necesitaremos ningún fichero wsdl que los describa, sino que directamente los podemos usar.
- La prctica tiene dos partes, una sin usar el fichero wsdl y otra usándolo.
PARTE 1 DE LA PRÁCTICA SIN FICHERO WSDL
- Crearemos un objeto de la case SoapServer para que haya un obejto en el servidor esperadno a que haya una solicitud del cliente y atenderla
- Para ello crearemos el fichero servicio.php
<?php require_once('server.php'); //Sin WSDL -> uri es obligatorio $server = new SoapServer(null, array('uri'=>"aquí poner el directorio donde tengamos el servicio")); $server->setClass('Server'); $server->handle(); ?>
- Observa que creamos un objeto del tipo SoaoServer
- Cargamos en ese objeto la clase que contine los métodos del servicio
- con handle generamos la respuesta del fichero html.
Usar el servicio
- Ahora ya tenemos el servicio y el objeto que esta escuchando esperando que alguien quiera usarlo
- implementamos el fichero cliente
- En él instanciamos un objeto de la clase SoapClient como se ve en el fichero descrito a continuación
<?php $url="especificar la ubicación absoluta del fichero que contiene el objeto SoapServer"; $uri="especificar el directorio donde está el fichero" //Creamos un cliente para llamar a esa URL. //Es obligatorio establecer el parámetro 'uri' al no tener WSDL , igual que ocurría al instanciar el objeto SoapServer $cliente = new SoapClient(null, array('location'=>$url,'uri'=>$uri"http://localhost/Saop")); //Ahora por ejemplo podemos consumir el servicio getFamilias(); $familias = $cliente->getFamilias(); print_r($familias); //Prueba el resto de servicios. ?>
USANDO WSDL
- Ahora estamos en el caso de que esta interfaz de los métodos (nombre, parámetros y valor de retorno) no son conocidas por los que las quieren usar
- Para ello las debemos publicar es un documento WSDL.
- Para generar este docuemento tenemos utilidades que automatzan (a mano es algo complicado, cuando menos tedioso ).
- Pasos a realizar
- Primero debemos comentar los métodos con las directivas o marcas usados por lenguejes que generan documentación como javadoc o phpDocumentor
- Entre las más importantes usarmeos @param @return
- Nos quedará
/** * Obtiene el PVP de un producto a partir de su código * @param string $cod@igo * @return float * * */ public function getPVP($codigo){ $producto = DB::obtieneProducto($codigo); return $producto->getPVP(); ...
- Entre los tipos usaremos int para entero string para caracter string[] para un array o registro
- Una vez hecho esto procedemos a generar un fichero php para que usando [WSDLDocument|http://code.google.com/p/wsdldocument/] se nos genere el fichero correspondiente
- como indican en los apuntes escribimos el fichero genera.php
<?php //serverW.php es el fichero descrito anteriormente, donde se implementan los métodos que se se ofrecen require_once 'serverW.php'; require_once'WSDLDocument.php'; //script que generará el fichero xml $url="Especifica la ubiación del fichero servidor con los comentarios @param..." $uri="especifica la ubiación de los ficheros dominio de nombres" //serviciow.php es el fichero que genera el objeto servidor soap $accion = new WSDLDocument("serverW",$url,$uri); echo $accion->saveXML(); //Genera el en navegador el fichero xml que hay que revisar /* LOS PARAMETROS DE WSDLDOCUMENT( ) 1º: El nombre de la clase que gestionará las peticiones al servicio. 2º: La URL en que se ofrece el servicio. 3º: El espacio de nombres destino. * */ ?>
- Revisa la cabecera del xml por si tubieras que añadir algún nombre de dominio ns, fíjate en los ejemplos de los apuntes
- Coge el contenido que sale por la pantalla del navegador y pégala en un fichero. nombralo con extensión xml
Generando la clase a partir del wsdl wsdl2php
Ahora tenemos el xml que describe el servicio soap el fichero serviciow.wsdl.xml Nuestro objeto servidor deberá publicar el interfaz de los métodos que servimos
<?php require_once('serverW.php'); //En este caso especificmos el fichero de descripcion del servicio generado anteriormente con la herramienta '''''WSDLDocument''''' $server = new SoapServer("ubicación del fichero xml"); $server->setClass('ServerW'); $server->handle(); ?>
- Ahora instalamos la herramienta wsdl2php para generar un fichero php en la máquina cliente que contiene los métodos del servidor que podemos usar según las especificaciones del fichero wsdl
- Descargamos
http://sourceforge.net/projects/wsdl2php/
- Instalamos
sudo pear install wsdl2php-0.2.1-pear.tgz
- ahora generamos la clase a partir de la especificación wsdl y podemos usar en el cliente
wsdl2php serviciow.wsdl.xml
y generamos un fichero. Si observamos al final del fichero wsdl
<wsdl:service name="ServerW"> <wsdl:documentation>Clase ServerW</wsdl:documentation> <wsdl:port name="ServerWPort" binding="tns:ServerWBinding"> <soap-env:address location="http://localhost/Saop4/serviciow.php"/> </wsdl:port> </wsdl:service>
- El nombre del fichero que genera es ServerW.php
- Si analizamos este fichero
<?php /** * ServerW class * * Clase ServerW * * @author {author} * @copyright {copyright} * @package {package} */ class ServerW extends SoapClient { private static $classmap = array( ); public function ServerW($wsdl = "serviciow.wsdl.xml", $options = array()) { foreach(self::$classmap as $key => $value) { if(!isset($options['classmap'][$key])) { $options['classmap'][$key] = $value; } } parent::__construct($wsdl, $options); } /** * Obtiene el PVP de un producto a partir de su código * * @param string $codigo * @return float */ public function getPVP($codigo) { return $this->__soapCall('getPVP', array($codigo), array( 'uri' => 'http://localhost/Saop4', 'soapaction' => '' ) ); } //Así para el resto de métodos que puedo consumir por que el servidor nos ofrece. ?>
- Tenemos las clases que el servidor nos ofrece y podemos usar facilmente
Usando las clases del servicio
- Ahora usamos la clase generada anteriormente
- Esta clase que extiende SoapCliente
- En ella tenemos los métodos que el servidor ofrece como un servicio
- Lo ejecutamos y verificamos su funcionamiento.
<?php require_once 'ServerW.php'; //Instanciamos un objeto de la case ServerW //Esta clase se ha generado automáticamente por la herramienta wsdl2php $cliente = new ServerW(); // Probamos a obtener el array con todas las familias $familias = $cliente->getFamilias(); print_r($familias); print "<br />"; // Probamos a obtener todos los productos de una familia $productos = $cliente->getProductosFamilia("ORDENA"); print_r($productos); print "<br />"; // Probamos a obtener el precio de un producto $pvp = $cliente->getPVP("KSTMSDHC8GB"); print("El PVP es ".$pvp); print "<br />"; // Probamos a obtener el stock de un producto en una tienda $unidades = $cliente->getStock("KSTMSDHC8GB", 3); print("Existen ".$unidades." unidades"); ?>