7

我正在尝试使用在消息中使用超过 1 个命名空间的 nuSOAP(因为我在这里绑定到 PHP4)访问 WebService。那可能吗?

示例请求消息如下所示:

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

我试图遵循:

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

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

希望 nuSOAP 会尝试将这些名称与正确的名称空间和节点匹配。然后我尝试使用soapval() 来生成元素及其命名空间——但如果我调用一个操作,nuSOAP 会创建以下请求:

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

所以在“匹配”阶段出现了问题。

4

4 回答 4

5

在尝试了匹配之后,我找到了两种可能的解决方案:

1) 不要使用 WSDL 创建 nusoap_client 和 soapval() 来创建消息 这样做的缺点是消息包含大量开销(命名空间在每个元素中定义)。不太好。

2) 不要依赖参数的匹配,而是在 xml 中构造您的回复并将前缀的所有定义放在第一个元素中 - 例如

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

仍然不是一个很好的解决方案,但它有效:-)

于 2009-04-09T12:49:11.690 回答
4

在 Irwin 的帖子的基础上,我手动创建了 xml,然后让 nusoap 完成其余的工作。我的虚拟主机没有 php soap 扩展,所以我不得不使用 nusoap,而我尝试使用的 Web 服务需要每个标签上的命名空间(例如,在我的示例中的用户名和密码)。

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>';

然后我有一个错误说:

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

所以我走的是懒惰的路线,进入了 nusoap.php 并在第 7674 行之前添加了这段代码以使其满意:

    if(empty($this->operation)) {
        $this->operation = "";
    }
于 2010-06-08T21:41:11.237 回答
2

另一个绕过这个问题的方法是修改 nusoap_client::call() 函数。在 nusoap.php 中的这一行(版本 1.123 中的 7359)旁边:

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

我添加了这个:

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

它奏效了!因为我只需要这个库用于一个项目,所以我可以硬编码这个 hack。否则,我会挖掘更多并修改函数以接受数组而不是字符串作为命名空间参数。

于 2010-12-14T01:06:35.660 回答
0

是的,我一直有同样的问题(通过谷歌找到你的 q!)我遇到了这个: http ://www.heidisoft.com/blog/using-nusoap-consume-net-web-service- 10-min 这里,开发者在coe中创建消息的xml正文,然后使用nusoap提交。

于 2009-11-05T11:20:28.223 回答