2009-04-01 48 views
6

Estoy tratando de acceder a un servicio web usando nuSOAP (porque estoy obligado a PHP4 aquí) que usa más de 1 espacio de nombres en un mensaje. ¿Es eso posible?Cómo usar nuSOAP para mensajes con varios espacios de nombres

Un ejemplo mensaje de solicitud se vería así:

<soapenv:Envelope ... 
    xmlns:ns1="http://domain.tld/namespace1" 
    xmlns:ns2="http://domain.tld/namespace2"> 
    <soapenv:Header/> 
    <soapenv:Body> 
    <ns1:myOperation> 
     <ns2:Person> 
     <ns2:Firstname>..</ns2:Firstname> 
     .. 
     </ns2:Person> 
     <ns1:Attribute>..</ns1:Attribute> 
    </ns1:myOperation> 
    </soapenv:Body> 
</soapenv:Envelope> 

me trataron de lo siguiente:

$client = new nusoap_client("my.wsdl", true); 
$params = array(
    'Person' => array(
    'FirstName' => 'Thomas', 
    .. 
    ), 
    'Attribute' => 'foo' 
); 

$result = $client->call('myOperation', $params, '', 'soapAction'); 

con la esperanza de que NuSOAP sería tratar de coincidir con estos nombres a los espacios de nombres y nodos correctos. Luego trató de utilizar soapval() para generar los elementos y su espacio de nombres - pero si llamo a una operación, NuSOAP crea la petición siguiente:

<SOAP-ENV:Envelope ...> 
    <SOAP-ENV:Body> 
    <queryCCApplicationDataRequest xmlns="http://domain.tld/namespace1"/> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

Así que algo va mal durante la fase de "coincidencia".

Respuesta

5

Después de probar un poco con el juego, he encontrado dos soluciones posibles:

1) No utilice el WSDL para crear el nusoap_client y soapval() para crear el mensaje Esto tiene la desventaja de que el mensaje contiene mucha sobrecarga (el espacio de nombre se define en cada elemento). No muy bien.

2) En lugar de confiar en la coincidencia de parámetros, construya su respuesta en xml y coloque toda la definición de prefijos en el primer elemento, p.

$params = "<ns1:myOperation xmlns:ns1="..." xmlns:ns2="..."> 
     <ns2:Person> 
     <ns2:Firstname>..</ns2:Firstname> 
     .. 
     </ns2:Person> 
     <ns1:Attribute>..</ns1:Attribute> 
    </ns1:myOperation>"; 
Aún no

una muy buena solución, pero funciona :-)

+0

Acabo de probar su solución y funciona .... gracias hombre. –

0

sí, he estado teniendo este mismo problema (que se encuentra a su q través de Google!) Y me he encontrado con esto: http://www.heidisoft.com/blog/using-nusoap-consume-net-web-service-10-min Aquí, el desarrollador crea el cuerpo xml del mensaje en coe y luego usa nusoap para enviarlo.

+0

Hmm, parece que el enlace no funciona actualmente. Por lo que dices, parece que siguieron un enfoque similar (creando el xml "manualmente"), ¿verdad? – wilth

4

Sobre la base de la publicación de Irwin, creé el xml manualmente y nusoap hizo el resto. Mi webhost no tiene la extensión php soap, así que tuve que ir con nusoap, y el servicio web que estoy tratando de consumir requería los espacios de nombres en cada etiqueta (por ejemplo, en nombre de usuario y contraseña en mi ejemplo aquí).

require_once('lib/nusoap.php'); 

$client = new nusoap_client('https://service.somesite.com/ClientService.asmx'); 
$client->soap_defencoding = 'utf-8'; 
$client->useHTTPPersistentConnection(); // Uses http 1.1 instead of 1.0 
$soapaction = "https://service.somesite.com/GetFoods"; 

$request_xml = '<?xml version="1.0" encoding="utf-8" ?> 
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> 
    <env:Body> 
    <n1:GetFoods xmlns:n1="https://service.somesite.com"> 
     <n1:username>banjer</n1:username> 
     <n1:password>theleftorium</n1:password> 
    </n1:GetFoods> 
    </env:Body> 
</env:Envelope> 
'; 

$response = $client->send($request_xml, $soapaction, ''); 

echo '<h2>Request</h2><pre>' . htmlspecialchars($client->request, ENT_QUOTES) . '</pre>'; 
echo '<h2>Response</h2><pre>' . htmlspecialchars($client->response, ENT_QUOTES) . '</pre>'; 
echo '<h2>Debug</h2><pre>' . htmlspecialchars($client->getDebug(), ENT_QUOTES) . '</pre>'; 

Luego tuve un error que dice:

Notice: Undefined property: nusoap_client::$operation in ./lib/nusoap.php on line 7674 

Fui, el camino más fácil y entró en nusoap.php y añade este código antes de la línea 7674 para que sea feliz:

if(empty($this->operation)) { 
     $this->operation = ""; 
    } 
+0

Después de recorrer Internet durante días, esto es lo único que me ayudó a resolverlo. ¡Gracias! No obtuve ese error, pero tuve que configurar $ client-> endpoint = ''; – Cypher909

1

Otro omitir este problema sería una modificación de la función nusoap_client :: call(). Al lado de la esta línea (7359 en la versión 1.123) en nusoap.php:

$nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace);

que añade éste:

$nsPrefix = $this->wsdl->getPrefixFromNamespace("other_ns_name"); 

y funcionó! Como solo necesitaba esta biblioteca para un proyecto, estaba bien que codificara este truco. De lo contrario, me gustaría excavar más y modificar la función para aceptar matriz en lugar de cadena para un parámetro de espacio de nombres.

Cuestiones relacionadas