En este artículo les comparto como integrar la librería NuSoap 0.9.5 dentro de CodeIgniter 1.7.2, crearemos un servidor y luego un cliente. Es importante tener algunos conocimiento previos, para que comprendas que es lo que se está haciendo y posteriormente puedas hacer las modificaciones para adaptar este código a tus necesidades. Aquí algunas ligas que ayudan a esto.
http://www.youtube.com/watch?v=ye3T5bXqdDs
http://www.youtube.com/watch?v=s3igsOCMwcg
http://www.youtube.com/watch?v=TRg9zu9kuHw&feature=related
XML-RPC - Wikipedia, the free encyclopedia
Programming with NuSOAP Using WSDL
Tutorial sobre WEB SERVICES: SOAP | Maldita Internet
¿Que estilo de WSDL usar? « Ronaldalarconb's Blog
Which style of WSDL should I use?
Cómo controlar el formato general de Body en SOAP para un método de servicio Web
Descargar la Documentación de NuSOAP desde sourceforge (no olvides expandir las carpetas para ver todas las versiones disponibles)
Pasos para nuestro ejemplo:
- Verificar el archivo de configuración de nuestra aplicación
- Descargar la libreria NuSOAP desde sourceforge
- Copiar la libreria NuSoap dentro de CodeIgniter
- Crear nuestra propia libreria que cargue la de NuSoap
- Crear el servicio web
- Crear el cliente del servicio web
- Probar nuestro cliente con nuestro servicio web
- Probar nuestro cliente con otros servicios web en la red
Comencemos:
Paso 1.
Editar el archivo autoload.php ubicado en
system/application/config/
y verificar que el helper 'url' esté incluido en la lista, por ejemplo:$autoload['helper'] = array('url' , 'file');
Abrir el archivo config.php ubicado en
system/application/config/
y poner atención en las variables $config['base_url']
y $config['index_page']
, configurarlas si fuera necesario según la ruta de tu servidor web, en estos ejemplos quedaría algo así:| | URL to your CodeIgniter root. Typically this will be your base URL, | WITH a trailing slash: | | http://example.com/ | */ $config['server_protocol'] = strpos(strtolower($_SERVER['SERVER_PROTOCOL']), 'https') === false ? 'http' : 'https'; $config['base_url'] = $config['server_protocol']."://".$_SERVER['HTTP_HOST']."/CI_training/"; // cambiado por Ultiminio Ramos $config['server_root'] = $_SERVER['DOCUMENT_ROOT']; /* |-------------------------------------------------------------------------- | Index File |-------------------------------------------------------------------------- | | Typically this will be your index.php file, unless you've renamed it to | something else. If you are using mod_rewrite to remove the page set this | variable so that it is blank. | */ $config['index_page'] = "index.php"; /* |-------------------------------------------------------------------------- | URI PROTOCOL |-------------------------------------------------------------------------- | | This item determines which server global should be used to retrieve theEsto sólo es necesario para ubicar la URL del archivo WSDL $end_point = base_url().index_page().'/servidor_nusoap/index/wsdl'; que posteriormente se indica en el programa servidor de nuestro web service, obviamente siempre se podrá formar dicha URL como mejor prefieras.
Paso 2. Esta es la liga NuSOAP desde sourceforge (no olvides expandir las carpetas para ver todas las versiones disponibles)
Paso 3. Copiar la librería NuSoap dentro de CodeIgniter:
Dentro de
system/application/libraries/
crear la carpeta NuSOAP/
y colocar dentro los archivos descomprimidos de nusoap. Paso 4. Crear nuestra propia librería que cargue la de NuSoap.
Dentro de
system/application/libraries/
crear un archivo con el nombre Nu_soap.php
y hacer colocar el siguiente código:<?php /********************************************************************************* * @AUTOR: ULTIMINIO RAMOS GALAN. * @SISTEMA: CI_training. * @FECHA: 17/07/2010, 11:46:15 PM. * @ARCHIVO: Nu_soap.php * @DESCRIPCION: Libreria propia. * @Encoding file: UTF-8 * Notas: Convenciones de nombres de archivos, clases, metodos, * variables, estructuras de control {}, manejo de operadores, * etc, son adoptadas segun la guia de referencia de * CodeIgniter. ********************************************************************************/ if ( ! defined('BASEPATH')) exit('No se permite el acceso directo a las páginas de este sitio.'); class Nu_soap { function __construct() { // Por si se ejecuta en un servidor Windows // require_once(str_replace("\\", "/", APPPATH).'libraries/NuSOAP/lib/nusoap'.EXT); require_once('NuSOAP/lib/nusoap'.EXT); } // end Constructor function index($no_cache) { } // end function } // end Class /* End of file Nu_soap.php */
Paso 5. Crear el servicio web.
Dentro de
system/application/controllers/
crear un archivo con el nombre servidor_nusoap.php
y colocar el siguiente código:<?php /********************************************************************************* * @AUTOR: ULTIMINIO RAMOS GALAN. * @SISTEMA: CI_training. * @FECHA: 19/07/2010, 01:04:51 PM. * @ARCHIVO: servidor_nusoap.php * @DESCRIPCION: Controlador. * @Encoding file: UTF-8 * Notas: Convenciones de nombres de archivos, clases, metodos, * variables, estructuras de control {}, manejo de operadores, * etc, son adoptadas segun la guia de referencia de * CodeIgniter. ********************************************************************************/ if ( ! defined('BASEPATH')) exit('No se permite el acceso directo a las páginas de este sitio.'); class Servidor_nusoap extends Controller { function __construct() { parent::Controller(); // Libreria personalizada que hicimos previamente para integrar la clase NuSoap con CI $this->load->library('nu_soap'); // Instanciamos la clase servidor de nusoap $this->NuSoap_server = new nusoap_server(); // Creamos el End Point, es decir, el lugar donde la petición cliente va a buscar la estructura del WSDL // aunque hay que recordar que nusoap genera dinámicamente dicha estructura XML $end_point = base_url().index_page().'/servidor_nusoap/index/wsdl'; // Indicamos cómo se debe formar el WSDL $this->NuSoap_server->configureWSDL('UsuariosWSDL', 'urn:UsuariosWDSL', $end_point, 'rpc'); $this->NuSoap_server->wsdl->addComplexType( 'Usuarios' # Creamos nuestro propio tipo de datos, llamado Usuarios, lo vamos a utilizar para regresar la respuesta , 'complexType' # Es de tipo complejo, es decir, un array o array asociativo , 'array' # Su equivalencia en PHP en este caso, es de tipo array, ('struct' equivale a array asociativo) , '' # Composición: 'all' | 'sequence' | 'choice', en nuestro caso no aplica , 'SOAP-ENC:Array' # Cómo se debe tratar y validar esta estructura de dato , array( # Los elementos del array 'id' => array('name' => 'id', 'type' => 'xsd:int') , 'nombre' => array('name' => 'nombre', 'type' => 'xsd:string') , 'apellidos' => array('name' => 'apellidos', 'type' => 'xsd:string') ) ); $this->NuSoap_server->register( // crear en forma de clase (controller..nombre del método) 'Servidor_nusoap..obtenerUsuario' # El nombre de la función PHP: Clase.método ó Clase..método , array('id' => 'xsd:int') # Qué datos recibe , array('return' => 'tns:Usuarios') # Qué datos regresa, aquí se aprecia nuestro propio tipo de datos que definimos en addComplexType() , 'urn:UsuariosWSDL' # El elemento namespace de nuestro método , 'urn:UsuariosWSDL#obtenerUsuario' # La acción u operación de nuestro método , 'rpc' # El estilo del XML , 'encoded' # Cómo se usa: 'literal' | 'encode' , "Provee el nombre completo de un usuario del cual se conoce su ID." # Texto de ayuda de nuestro método ); } // end Constructor function index() { $_SERVER['QUERY_STRING'] = ''; if ( $this->uri->segment(3) == 'wsdl' ) { $_SERVER['QUERY_STRING'] = 'wsdl'; } // endif $this->NuSoap_server->service(file_get_contents('php://input')); } // end function function obtenerUsuario($id_usuario) { $row = array( array( 'id' => $id_usuario , 'nombre' => 'Ultiminio' , 'apellidos' => 'Ramos Galan' ) ); /* Este bloque muestra como se puede trabajar con un modelo de CodeIgniter */ /* // Obtener el superobjeto de CodeIgniter, get_instance() sirve para tener acceso a todos los métodos del framework $CI =& get_instance(); $CI->load->model('mod_cruds'); $obj_db_result = $CI->mod_cruds->traer_usuario($id_usuario); $row = array( array( 'id' => $obj_db_result[0]->id_meta_campo , 'campo' => $obj_db_result[0]->meta_campo , 'etiqueta' => $obj_db_result[0]->meta_etiqueta ) ); */ return $row; } // end function } // end Class /* End of file servidor_nusoap.php */Paso 6. Crear el cliente del servicio web.
Dentro de
system/application/controllers/
crear un archivo con el nombre cliente_nusoap.php
y colocar el siguiente código:<?php /********************************************************************************* * @AUTOR: ULTIMINIO RAMOS GALAN. * @SISTEMA: CI_training. * @FECHA: 17/07/2010, 05:41:16 PM. * @ARCHIVO: cliente_nusoap.php * @DESCRIPCION: Controlador. * @Encoding file: UTF-8 * Notas: Convenciones de nombres de archivos, clases, metodos, * variables, estructuras de control {}, manejo de operadores, * etc, son adoptadas segun la guia de referencia de * CodeIgniter. ********************************************************************************/ if ( ! defined('BASEPATH')) exit('No se permite el acceso directo a las páginas de este sitio.'); class Cliente_nusoap extends Controller { function __construct() { parent::Controller(); $this->load->library('nu_soap'); } // end Constructor function index() { } // end function /* * Método para probar el servicio web creado con la integración de NuSoap + CodeIgniter */ function traer_usuario() { // Estos parametros no los necesitamos en este ejemplo, pero los pongo para que tengas idea de // todo lo que se puede configurar en nuestra petición $proxyhost = isset($_POST['proxyhost']) ? $_POST['proxyhost'] : ''; $proxyport = isset($_POST['proxyport']) ? $_POST['proxyport'] : ''; $proxyusername = isset($_POST['proxyusername']) ? $_POST['proxyusername'] : ''; $proxypassword = isset($_POST['proxypassword']) ? $_POST['proxypassword'] : ''; // Instanciamos la clase cliente de nusoap $this->client = new nusoap_client('http://localhost/CI_training/index.php/servidor_nusoap/index/wsdl', 'wsdl', $proxyhost, $proxyport, $proxyusername, $proxypassword); // Cachamos algún error en los parámetros dados $err = $this->client->getError(); if ($err) { echo '<h2>Constructor error</h2><pre>' . $err . '</pre>'; } // endif // ¡Importante! // Hacemos la llamada al método en forma de clase (Controlador..Nombre del método) $call = 'Servidor_nusoap..obtenerUsuario'; $id_usuario = rand(1, 999); // un número aleatorio para la prueba $parts = array('id' => $id_usuario); $result = $this->client->call($call, $parts); // Gestionamos la respuesta $this->_manage_response($result, $this->client->fault, $this->client->getError()); return; } // end function /* * Acción predeterminada para las pruebas del webservices cliente */ private function _manage_response($result, $is_fault, $is_error) { // Fallas if ($is_fault) { echo '<h2>Falla:</h2><pre>'; print_r($result); echo '</pre>'; echo '<h2>Request</h2><pre>' . htmlspecialchars($this->client->request, ENT_QUOTES) . '</pre>'; echo '<h2>Response</h2><pre>' . htmlspecialchars($this->client->response, ENT_QUOTES) . '</pre>'; echo '<h2>Debug</h2><pre>' . htmlspecialchars($this->client->debug_str, ENT_QUOTES) . '</pre>'; } else { // Errores if ($is_error) { // Imprimir los detalles del error echo '<h2>Error:</h2><pre>' . $is_error . '</pre>'; echo '<h2>Request</h2><pre>' . htmlspecialchars($this->client->request, ENT_QUOTES) . '</pre>'; echo '<h2>Response</h2><pre>' . htmlspecialchars($this->client->response, ENT_QUOTES) . '</pre>'; echo '<h2>Debug</h2><pre>' . htmlspecialchars($this->client->debug_str, ENT_QUOTES) . '</pre>'; } else { // ¡Que felicidad, desplegamos el resultado! echo '<h2>Resultado:</h2><pre>'; print_r($result); echo '</pre>'; } } return; } // end function } // end Class /* End of file cliente.php */Paso 7. Probar nuestro cliente con nuestro servicio web.
7.2 Debe aparecer una página con la lista y operaciones del web service
7.3 Haciendo clic sobre el nombre del método disponible, que en nuestro caso es Servidor_nusoap..obtenerUsuario debe aparecer un recuadro con la descripción de este método
Nota: si das clic sobre la liga de View the WSDL for the serv... te aparecerá un error 404 de page no found, pero no te preocupes en realidad, la ruta correcta para ver la estructura XML de nuestro servicio web la puedes ver en la información que aparece en el recuadro, en el rubo de EndPoint, esa ruta la pegas en la URL de tu navegador y podrás ver la estructura XML que nusoap nos hizo el favor de crear.
7.4 Ahora probemos el cliente, ejecuta tu controlador desde la URL de tu navegador
7.5 El resultado se verá como este:
Paso 8. Probar nuestro cliente con otros servicios web en la red.
Aquí dejo el código para que veas cómo se puede utilizar, para estos ejemplos e incluido consumir servicios para:
- Obtener la liga para descargar archivos de video de YouTube
- Obtener el clima en Estados Unidos de Norte América
- Obtener el tipo de cambio de moneda entre dos países
<?php /********************************************************************************* * @AUTOR: ULTIMINIO RAMOS GALAN. * @SISTEMA: CI_training. * @FECHA: 17/07/2010, 05:41:16 PM. * @ARCHIVO: cliente_nusoap.php * @DESCRIPCION: Controlador. * @Encoding file: UTF-8 * Notas: Convenciones de nombres de archivos, clases, metodos, * variables, estructuras de control {}, manejo de operadores, * etc, son adoptadas segun la guia de referencia de * CodeIgniter. ********************************************************************************/ if ( ! defined('BASEPATH')) exit('No se permite el acceso directo a las páginas de este sitio.'); class Cliente_nusoap extends Controller { function __construct() { parent::Controller(); $this->load->library('nu_soap'); } // end Constructor function index() { } // end function /* * Método para obtener la liga para para descargar archivos de video de YouTube */ function get_youtube() { $proxyhost = isset($_POST['proxyhost']) ? $_POST['proxyhost'] : ''; $proxyport = isset($_POST['proxyport']) ? $_POST['proxyport'] : ''; $proxyusername = isset($_POST['proxyusername']) ? $_POST['proxyusername'] : ''; $proxypassword = isset($_POST['proxypassword']) ? $_POST['proxypassword'] : ''; $this->client = new nusoap_client('http://www.ecubicle.net/youtubedownloader.asmx?WSDL', 'wsdl', $proxyhost, $proxyport, $proxyusername, $proxypassword); $err = $this->client->getError(); if ($err) { echo '<h2>Constructor error</h2><pre>' . $err . '</pre>'; } // endif $method = isset($_GET['method']) ? $_GET['method'] : 'function'; $call = 'GetDownloadURL'; $parts = array('fileURL' => 'http://www.youtube.com/watch?v=s3igsOCMwcg'); $result = $this->client->call($call, $parts); echo anchor($result['GetDownloadURLResult'], 'Descargar archivo FLV'); $this->_manage_response($result, $this->client->fault, $this->client->getError()); return; } // endfunction /* * Método para obtener el clima en Estados Unidos de Norte América */ function get_weather() { $proxyhost = isset($_POST['proxyhost']) ? $_POST['proxyhost'] : ''; $proxyport = isset($_POST['proxyport']) ? $_POST['proxyport'] : ''; $proxyusername = isset($_POST['proxyusername']) ? $_POST['proxyusername'] : ''; $proxypassword = isset($_POST['proxypassword']) ? $_POST['proxypassword'] : ''; $this->client = new nusoap_client('http://ws.cdyne.com/WeatherWS/Weather.asmx?wsdl', 'wsdl', $proxyhost, $proxyport, $proxyusername, $proxypassword); $err = $this->client->getError(); if ($err) { echo '<h2>Constructor error</h2><pre>' . $err . '</pre>'; } // endif $method = isset($_GET['method']) ? $_GET['method'] : 'function'; $call = 'GetCityWeatherByZIP'; $parts = array('ZIP' => '16034'); $result = $this->client->call($call, $parts); $this->_manage_response($result, $this->client->fault, $this->client->getError()); return; } //end function /* * Método para obtener el tipo de cambio entre dos países */ function get_currency2() { $proxyhost = isset($_POST['proxyhost']) ? $_POST['proxyhost'] : ''; $proxyport = isset($_POST['proxyport']) ? $_POST['proxyport'] : ''; $proxyusername = isset($_POST['proxyusername']) ? $_POST['proxyusername'] : ''; $proxypassword = isset($_POST['proxypassword']) ? $_POST['proxypassword'] : ''; $this->client = new nusoap_client('http://www.webservicex.net/CurrencyConvertor.asmx?wsdl', 'wsdl', $proxyhost, $proxyport, $proxyusername, $proxypassword); $err = $this->client->getError(); if ($err) { echo '<h2>Constructor error</h2><pre>' . $err . '</pre>'; } // endif $method = isset($_GET['method']) ? $_GET['method'] : 'function'; $call = 'ConversionRate'; $parts = array('FromCurrency' => 'EUR', 'ToCurrency' => 'MXN'); $result['euro'] = $this->client->call($call, $parts); $parts = array('FromCurrency' => 'USD', 'ToCurrency' => 'MXN'); $result['dolar'] = $this->client->call($call, $parts); $parts = array('FromCurrency' => 'JPY', 'ToCurrency' => 'MXN'); $result['Yen'] = $this->client->call($call, $parts); $this->_manage_response($result, $this->client->fault, $this->client->getError()); return; } //end function /* * Método para probar el servicio web creado con la integración de NuSoap + CodeIgniter */ function traer_usuario() { // Estos parametros no los necesitamos en este ejemplo, pero los pongo para que tengas idea de // todo lo que se puede configurar en nuestra petición $proxyhost = isset($_POST['proxyhost']) ? $_POST['proxyhost'] : ''; $proxyport = isset($_POST['proxyport']) ? $_POST['proxyport'] : ''; $proxyusername = isset($_POST['proxyusername']) ? $_POST['proxyusername'] : ''; $proxypassword = isset($_POST['proxypassword']) ? $_POST['proxypassword'] : ''; // Instanciamos la clase cliente de nusoap $this->client = new nusoap_client('http://localhost/CI_training/index.php/servidor_nusoap/index/wsdl', 'wsdl', $proxyhost, $proxyport, $proxyusername, $proxypassword); // Cachamos algún error en los parámetros dados $err = $this->client->getError(); if ($err) { echo '<h2>Constructor error</h2><pre>' . $err . '</pre>'; } // endif // ¡Importante! // Hacemos la llamada al método en forma de clase (Controlador..Nombre del método) $call = 'Servidor_nusoap..obtenerUsuario'; $id_usuario = rand(1, 999); // un número aleatorio para la prueba $parts = array('id' => $id_usuario); $result = $this->client->call($call, $parts); // Gestionamos la respuesta $this->_manage_response($result, $this->client->fault, $this->client->getError()); return; } // end function /* * Acción predeterminada para las pruebas del web service cliente */ private function _manage_response($result, $is_fault, $is_error) { // Fallas if ($is_fault) { echo '<h2>Falla:</h2><pre>'; print_r($result); echo '</pre>'; echo '<h2>Request</h2><pre>' . htmlspecialchars($this->client->request, ENT_QUOTES) . '</pre>'; echo '<h2>Response</h2><pre>' . htmlspecialchars($this->client->response, ENT_QUOTES) . '</pre>'; echo '<h2>Debug</h2><pre>' . htmlspecialchars($this->client->debug_str, ENT_QUOTES) . '</pre>'; } else { // Errores if ($is_error) { // Imprimir los detalles del error echo '<h2>Error:</h2><pre>' . $is_error . '</pre>'; echo '<h2>Request</h2><pre>' . htmlspecialchars($this->client->request, ENT_QUOTES) . '</pre>'; echo '<h2>Response</h2><pre>' . htmlspecialchars($this->client->response, ENT_QUOTES) . '</pre>'; echo '<h2>Debug</h2><pre>' . htmlspecialchars($this->client->debug_str, ENT_QUOTES) . '</pre>'; } else { // ¡Que felicidad, desplegamos el resultado! echo '<h2>Resultado:</h2><pre>'; print_r($result); echo '</pre>'; } } return; } // end function } // end Class /* End of file cliente.php */Eso es todo, espero que esto te sirva para que inicies la aventura de los Web Services con CodeIgniter + NuSOAP con PHP.
Me resultó de gran utilidad. Muchas gracias por el tutorial!
ResponderEliminarEl único detalle, una pequeñísima omisión: Para que el proyecto funcione correctamente es necesario haber cargado el "URL helper". La manera más comoda es agregarlo al array $autoload['helper'] = array('url'); definido en /application/config/autoload.php
Tienes mucha razón Leo, voy a editar el artículo para hacer la aclaración, gracias por hacerme la observación del helper.
ResponderEliminarHombre, ud sabe como implementar esto para code igniter 2.1?
Eliminarvoy a probarlo muy pronto, mil gracias por adelantado y prometo mostrarte el servicio corriendo.
ResponderEliminarSólo una pregunta, como hacemos si queremos crear mas de un tipo diferente de peticion?
ResponderEliminarpor ejemplo:
registrarse
logearse
mostrar datos
...
tendriamos que crear varios ws.
Se me ocurre que quizás parametrizando la peticion con un flag, para conocer el tipo de peticion... pero es poco elegante.
Muito bom o tutorial, funcionou perfeitamente.
ResponderEliminarGran tutorial!, igual no puedo hacer que se comuniquen, funciona el server y el wsdl pero en el punto 7.5 el cliente retorna vacio, cambie el codigo de traer usuario por el de get_currency2 y funciona perfecto, asi q creo q es un problema de rutas, alguna idea?
ResponderEliminarExcelente tutorial, lo probe en CI 2.0 y no tengo problemas
ResponderEliminarMuchas Gracias
Atte V_OMAR
Excelente trabajo, pero tengo una duda...
ResponderEliminarPero si mi estructura en el addComplexType, tiene un campo que en lugar de un string es a su vez un array ¿como se define?
Buenas...la verdad no entiendo porque me sale este error:
ResponderEliminarFatal error: Class 'Controller' not found in C:\wamp\www\CI_training\application\controllers\servidor_nusoap.php on line 17
gracias...
Si tienes una versión 2.0 o superior de CodeIgniter, debes poner CI_Controller
Eliminary Para el contructor: parent::__construct();
muchas gracias por su ayuda
Eliminarhola, todos los valores que inicio me sale la siguiente respuesta
ResponderEliminarUsing $this when not in object context in
Yo estoy tratando de integrar con CI 2.0, pero me falta resolver un pequeño problema. Este error wsdl error: XML error parsing WSDL from http://127.0.0.1/sarh-marcelog/index.php/services/server_1/test_1/wsdl on line 10: Reserved XML Name
EliminarLocalize el problema pero no se bien si modificar la clase nusoap_server, coloca un header que CI luego sobreescribe, ademas la implementación del mensaje SOAP coloca un header Content-Type: text/html; charset=ISO-8859-1 me imagino que debería ser utf-8 por el tema del español.
Saludos. Si logro avanzar posteo lo que logre.
logrado?
EliminarMuito obrigado
ResponderEliminarMe ajudou muito.
Julio
jcasilva86@gmail.com
Excelente! Me gustaría saber si puedes o tienes un tutorial, igual de claro y explicito, que toque el tema de los diferentes tipos de validaciones, autorización o autenticación, para subir el nivel de seguridad de los servicios.
ResponderEliminarbuenos dias, tengo problema con las constantes EXT y APPPATH cuando se crea la instancia de la libreria nusoap, ayuda por favor, antemano gracias.
ResponderEliminar