La petada del día de hoy ha sido con php 5.3 y el cliente de SOAP ( SoapClient::__soapCall() )
La historia es que estamos implementando un cliente para usar un webservice de un tercero y nos estaba petando siempre, por que su lado tampoco lo tienen muy apañao y nos devolvía unas trazas de java muy feas 😀
El caso es que al final me he liado a tracear las conexiones tcp para ver qué estabamos mandando y veía todo el rato que envíamos sólo un parámetro cuando tenían que ser dos. Después de volverme loco durante un rato, me ha funcionado haciendo la llamada directamente desde el objeto cliente.
Como esto es un carajal vamos a ver ejemplos reales ( he usado wireshark por que estoy perruno 😀 ) :
el script en php es este:
[shell]
<?php
try {
$wsdl = ‘http://localhost:8080/autenticacion/validateuser?WSDL’;
$params = array();
$params[‘authentication’] = SOAP_AUTHENTICATION_BASIC;
$params[‘login’] = «jorge» ;
$params[‘password’] = «senin» ;
$params[‘trace’] = true ;
$client = new SoapClient ( $wsdl ,$params ) ;
$validation = array ( ‘usuario’ => ‘pepe’, ‘password’ => ‘123456’ );
$result = $client->__soapCall ( ‘autenticar’ , $validation );
var_dump ( $result );
}
//gestion de excepciones
catch (Exception $e) {
print «SOAP Error: » . $e->getMessage();
print $client->__getLastResponse( );
}
?>
[/shell]
Devuelve:
[shell]
<?xml version=»1.0″ encoding=»UTF-8″?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV=»http://schemas.xmlsoap.org/soap/envelope/» xmlns:ns1=»http://www.senin.org/autenticacion»>
<SOAP-ENV:Body>
<ns1:PeticionLogin/><param1>123456</param1>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
[/shell]
Como veis falta un parámetro, falta el username, sólo me envía la password
pero si hago la llamada de esta forma :
[shell]
$result = $client->autenticar( $validation );
[/shell]
Funciona correctamente :
[shell]
<pre>
<SOAP-ENV:Envelope xmlns:SOAP-ENV=»http://schemas.xmlsoap.org/soap/envelope/» xmlns:ns1=»http://www.senin.org/autenticacion»>
<SOAP-ENV:Body>
<ns1:PeticionLogin>
<ns1:usuario>jorge</ns1:Usuari>
<ns1:password>123456</ns1:Contrasenya>
</ns1:PeticionLogin>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
</pre>
[/shell]
Si veis difiere como se envía el SOAP.
He encontrado esta entrada en un foro de drupal :
http://drupal.org/node/1191790
Those calls are not equal, because the arguments are passed differently. __soapCall() splits up the arguments array into separate parameters, while directly calling the operation method passes the arguments array as is. Looks like your server implements a document/wrapped parameter scheme, which is unfortunately not supported by the PHP SOAP client. You need to wrap the parameters yourself, your operation has only one complex data structure as parameter that contains the actual parameters as properties.
Y por hoy no está mal 😀
Deja una respuesta