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

我的未来我决定 提交于 2019-12-05 05:13:04

问题


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

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

<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-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 UniqueIdentifier and CallingSystem parameters are prefixed with ns1 in the soap-ui request.

I've tried using passing SoapVar objects to the SoapClient call but this does not augment the parameter tags and prefix them with ns1.

I know that WEB is a valid CallingSystem value as the XSD specifies it, and it works when using soap-ui.

My current SoapClient code:

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 post but I was hoping there might be a cleaner implementation.

Update: Used a solution from this question but 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)
);

回答1:


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

Note, SoapVar has options to specify the namespace of each 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:

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

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




回答2:


Use a SoapVar to namespace the GenericSearchRequest fields:

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


来源:https://stackoverflow.com/questions/17855171/php-soapclient-how-to-prefix-soap-parameter-tag-name-with-namespace

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!