【问题标题】:PHP SoapClient: How to prefix SOAP parameter tag name with namespace?PHP SoapClient:如何在 SOAP 参数标记名称前加上命名空间?
【发布时间】:2013-07-25 10:16:31
【问题描述】:

我正在使用 PHP 的 SoapClient 来使用 SOAP 服务,但收到一个错误,即 SOAP 服务无法看到我的参数。

<tns:GenericSearchResponse xmlns:tns="http://.../1.0">
  <tns:Status>
    <tns:StatusCode>1</tns:StatusCode>
    <tns:StatusMessage>Invalid calling system</tns:StatusMessage>
  </tns:Status>
</tns:GenericSearchResponse>

XML PHP 的 SoapClient 发送 SOAP 调用:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:ns1="http://.../1.0">
  <SOAP-ENV:Body>
    <ns1:GenericSearchRequest>
      <UniqueIdentifier>12345678</UniqueIdentifier>
      <CallingSystem>WEB</CallingSystem>
    </ns1:GenericSearchRequest>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

我最初使用的是soap-ui,它在使用相同的WSDL 时可以成功运行。 XML soap-ui 发送调用:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:ns1="http://.../1.0">
  <SOAP-ENV:Body>
    <ns1:GenericSearchRequest>
      <ns1:UniqueIdentifier>12345678</ns1:UniqueIdentifier>
      <ns1:CallingSystem>WEB</ns1:CallingSystem>
    </ns1:GenericSearchRequest>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

区别在于UniqueIdentifierCallingSystem 参数在soap-ui 请求中以ns1 为前缀。

我尝试使用将SoapVar 对象传递给SoapClient 调用,但这不会增加参数标签并在它们前面加上ns1

我知道 WEB 是一个有效的 CallingSystem 值,因为 XSD 指定了它,并且在使用 soap-ui 时它可以工作。

我当前的SoapClient 代码:

try {
  $client = new SoapClient($wsdl, array('trace' => 1));
  $query = new stdClass;
  $query->UniqueIdentifier = $id;
  $query->CallingSystem = 'WEB';
  $response = $client->GenericUniqueIdentifierSearch($query);
} catch (SoapFault $ex) {
  $this->view->error = $ex->getMessage();
  ...
}

我找到了this blog post,但我希望有一个更简洁的实现。

更新: 使用了solution from this question,但很笨重:

$xml = "<ns1:GenericSearchRequest>"
     . "<ns1:UniqueIdentifier>$id</ns1:UniqueIdentifier>"
     . "<ns1:CallingSystem>WEB</ns1:CallingSystem>"
     . "</ns1:GenericSearchRequest>";
$query = new SoapVar($xml, XSD_ANYXML);

$response = $this->client->__SoapCall(
    'GenericUniqueIdentifierSearch',
    array($query)
);

【问题讨论】:

    标签: php soap soap-client


    【解决方案1】:

    我发现这样做的合理方法是结合使用 SoapVar 和 SoapParam。

    注意,SoapVar 可以选择指定每个 var 的命名空间。

    所以你的代码应该是这样的:

    $wrapper = new StdClass;
    $wrapper->UniqueIdentifier = new SoapVar($id, XSD_STRING, "string", "http://www.w3.org/2001/XMLSchema", "UniqueIdentifier", "ns1");
    $wrapper->CallingSystem = new SoapVar("WEB", XSD_STRING, "string", "http://www.w3.org/2001/XMLSchema", "CallingSystem", "ns1");
    $searchrequest = new SoapParam($wrapper, "GenericSearchRequest");
    
    try{
        $response = $this->client->GenericUniqueIdentifierSearch($searchrequest);
    }catch(Exception $e){
        die("Error calling method: ".$e->getMessage());
    }
    

    如果您遇到属性和方法获取不同命名空间的问题,请尝试将 SoapVar 的命名空间指定为信封中定义的 url(在您的示例中:“http://.../1.0”),例如:

    $wrapper->UniqueIdentifier = new SoapVar($id, XSD_STRING, "string", "http://www.w3.org/2001/XMLSchema", "UniqueIdentifier", "http://.../1.0");
    

    有关所有 XSD_* 常量的列表,请参阅 Soap constants

    【讨论】:

      【解决方案2】:

      使用SoapVar 命名GenericSearchRequest 字段:

      $xml = "<ns1:GenericSearchRequest>"
           . "<ns1:UniqueIdentifier>$id</ns1:UniqueIdentifier>"
           . "<ns1:CallingSystem>WEB</ns1:CallingSystem>"
           . "</ns1:GenericSearchRequest>";
      $query = new SoapVar($xml, XSD_ANYXML);
      
      $response = $this->client->__SoapCall(
          'GenericUniqueIdentifierSearch',
          array($query)
      );
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-29
        • 1970-01-01
        • 1970-01-01
        • 2019-01-12
        • 1970-01-01
        • 2011-08-19
        • 2012-09-07
        • 1970-01-01
        相关资源
        最近更新 更多