Recientemente nos han llegado un par de proyectos en los que debemos consumir webservices SOAP para obtener datos. La verdad es que hacía bastante tiempo que no los veía en mi trabajo habitual. Hace algunos años eran muy habituales para casi cualquier cosa que implicase comunicación con fuentes externas, sin embargo los últimos años habían caído un poco en desuso para cosas sencillas puesto que complicaban bastante un trabajo que con una simple petición HTTP y un XML básico se podría resolver. Precisamente ésta ha sido siempre una de las mayores críticas al protocolo SOAP, el elevado consumo de ancho de banda para una sencilla petición.
Hasta ahora siempre había utilizado nusoap para realizar llamadas SOAP desde PHP, sin embargo me encontré con un problema al acceder a un servicio de un importante medio de comunicación internacional. La llamada con nusoap no devolvía resultados mientras que desde el sistema de pruebas html todo funcionaba correctamente.
Después de darle mil vueltas y no encontrar ningún error (otras peticiones al mismo servicio sí que funcionaban) me dí cuenta que PHP ya tiene un conjunto de funciones SOAP nativas, con lo que no necesitaría nusoap. La duda era saber si funcionaría bien, como así fue. Tras añadir la extensión adecuada surge una pequeña incompatibilidad. No puedes usar nusoap y las funcionas nativas en la misma instalación de PHP. Dicho de otro modo, si activas la extensión SOAP, nusoap dejará de funcionar y comenzará a lanzar mensajes de error ya que muchas de las funciones que utiliza tienen el mismo nombre que las nativas, que serían entonces nombres reservados. Si tienes alguna aplicación que utilice nusoap en la misma máquina tendrás que migrarla también para que utilice las funciones nativas.
El ejemplo de hoy será una sencilla llamada a un servicio que nos devuelve un listado de noticias.
El proceso es muy sencillo, necesitas la url del webservice, el método al que vas a llamar y los parámetros a pasarle y, como en cualquier servicio SOAP, te devolverá un XML.
-
$servicio="http://dominio.com/noticias?wsdl"; //url del servicio
-
$parametros[‘idioma’]="es";
-
$parametros[‘usuario’]="manolo";
-
$parametros[‘clave’]="tuclave";$client = new SoapClient($servicio, $parametros);
-
$result = $client->getNoticias($parametros);//llamamos al métdo que nos interesa con los parámetros
Con estas sencillas instrucciones ya tenemos en $result el XML resultado de la llamada al servicio. Como trabajar con el XML es un poco engorroso, lo convertimos a un array asociativo de manera que nos sea más sencillo procesar los datos, para ello utilizamos la función obj2array que indico a continuación.
-
-
$result = obj2array($result);
-
$noticias=$result[‘resultado’][‘noticias’];
-
-
//procesamos el resultado como con cualquier otro array
-
for($i=0; $i<$n; $i++){
-
$noticia=$noticias[$i];
-
$id=$noticia[‘id’];
-
//aquí iría el resto de tu código donde procesas los datos recibidos
-
}
-
-
function obj2array($obj) {
-
foreach ($obj as $key => $val) {
-
switch(true) {
-
$out[$key] = obj2array($val);
-
break;
-
$out[$key] = obj2array($val);
-
break;
-
default:
-
$out[$key] = $val;
-
}
-
}
-
return $out;
-
}
En la segunda línea nos quedamos con los elementos del array que nos interesa procesar. Si no sabes qué devuelve tu webservice puedes hacer un var_dump($result) y verás todo el resultado. En nuestro caso, como es una secuencia de noticias, nos quedamos con el elemento que tiene esas noticias.
Como os habréis dado cuenta, no me he preocupado del control de errores al llamar al webservice. Eso os lo dejo como ejercicio a vosotros, que es agosto y no me apetece
. En el manual de PHP está toda la información.
Y eso es todo amigos, hoy ha sido un ejemplo sencillo pero muy útil cuando necesitas utilizar SOAP.


7 usuarios han comentado en " Consumiendo webservices SOAP desde PHP "
Feed Los comentarios para esta entrada TrackbackHolap que tal bueno el tuto. Tengo un problema con el SOAP de php. El problema es:
Al llamar un web service sin parametros la llamada me funciona perfectamente, pero al llamar un WS con parametros me sale el siguiente error :
Fatal error: Uncaught SoapFault exception: [soap:Server] System.Web.Services.Protocols.SoapException: Server was unable to process request. —> System.Data.SqlClient.SqlException: Procedure or function ‘GetBibleWordsByChapterAndVerse’ expects parameter ‘@BookTitle’, which was not supplied. at WebServicex.BibleWebservice.GetBibleWordsByChapterAndVerse(String BookTitle, Int32 chapter, Int32 Verse) — End of inner exception stack trace — in /home/cbarcos/htdocs/pruebas/soapCliente.php:35
Este es mi codigo:
$client = new SoapClient(”http://www.webservicex.net/BibleWebservice.asmx?wsdl”,array(’trace’ => 1));
$params =array(
new SoapParam(”Romans”,”BookTitle”),
new SoapParam(1,”chapter”),
new SoapParam(1,”Verse”)
);
$data = $client->__soapCall( ‘GetBibleWordsByChapterAndVerse’ , $params );
Espero me puedas ayudar gracias !!
Hola Fernando,
Prueba con este código, me ha funcionado bien:
“Romans”,
“chapter”=>1,
“Verse”=>1
);
$client = new SoapClient(”http://www.webservicex.net/BibleWebservice.asmx?wsdl”, $par);
$result = $client->GetBibleWordsByChapterAndVerse($parametros);
var_dump($result);
?>
Saludos,
Osus
Tengo un web Service que consumir y este requiere certificado para que pueda ser consumido, como hago para poder enviar el certificado? Gracias..
Hola,
No entiendo mucho donde va el certificado. Por favor, explica más detalladamente cual es el problema, qué quieres hacer, qué requerimientos tienes…
Buenas Tardes muy interesante el tutorial, quisiera saber de que manera debo proceder si debo consumir un servicio web que tengo diseñado en eclipse, por favor cualquier idea que puedan darme es bienvenida
Hola Melvil,
¿Podrías dar más detalles?
En principio un ws lo cuelgas de tu servidor web y lo consumes sin problemas.
hola, buen dia, quisiera saber si alguien me puede ayudar. quiero consumir un servicio wb hacho en .net, que devuelve un dataset, desde php. he buscando informacion y la verdad es muy poco lo que pude encontrar. gracias
Dejar una respuesta