WebServices con NuSOAP en PHP - Ejemplo 4 - Vista

Bueno, 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

<?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' => '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 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']) {
    // 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 {
        $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/>';
        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:











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.

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.