Como transferir archivos con NuSOAP

Gracias 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 archivos

El 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-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 archivos

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

?>


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.