PHP SoapClient:如何为 SOAP 参数标记名称加上命名空间的前缀?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17855171/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 16:34:29  来源:igfitidea点击:

PHP SoapClient: How to prefix SOAP parameter tag name with namespace?

phpsoapsoap-client

提问by Greg K

I'm using PHP's SoapClientto consume a SOAP service but am receiving an error that the SOAP service cannot see my parameters.

我正在使用 PHPSoapClient来使用 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>

The XML PHP's SoapClient sends for the SOAP call:

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>

I used soap-ui initially, that works successfully when consuming the same WSDL. The XML soap-ui sends for the call:

我最初使用了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>

The difference being the UniqueIdentifierand CallingSystemparameters are prefixed with ns1in the soap-ui request.

不同之处在于UniqueIdentifierCallingSystem参数ns1在soap-ui 请求中带有前缀。

I've tried using passing SoapVarobjects to the SoapClientcall but this does not augment the parameter tags and prefix them with ns1.

我试过使用将SoapVar对象传递给SoapClient调用,但这不会增加参数标签并以ns1.

I know that WEBis a valid CallingSystemvalue as the XSD specifies it, and it works when using soap-ui.

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

My current SoapClientcode:

我目前的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();
  ...
}

I found this blog postbut I was hoping there might be a cleaner implementation.

我找到了这篇博文,但我希望可能有一个更清晰的实现。

Update:Used a solution from this questionbut is pretty clunky:

更新:使用了这个问题解决方案,但非常笨重:

$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)
);

回答by Nezar Nielsen

The reasonable way I found to do this, is to use a combination of SoapVar and SoapParam.

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

Note, SoapVar has options to specify the namespace of each var.

注意,SoapVar 有选项来指定每个 var 的命名空间。

So your code should be something like:

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

$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());
}

If you get an issue where the attributes and the method are getting different namespaces, try specifying the namespace for your SoapVar as the url as defined in your envelope (in your example: "http://.../1.0") like:

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

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

See the Soap constantsfor a list of all XSD_* constants.

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

回答by Greg K

Use a SoapVarto namespace the GenericSearchRequestfields:

使用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)
);