2013-07-25 111 views
0

我使用PHP的SoapClient來使用SOAP服務,但接收到SOAP服務無法看到我的參數的錯誤。PHP SoapClient:如何給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> 

我用肥皂UI最初,消耗相同WSDL時成功地工作。該XML皁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參數與所述皁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) 
); 

回答

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

合理的方式,我發現做到這一點,是使用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的網址爲您的信封定義(在你的榜樣: 「http://.../1.0」),如:

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

所有XSD_ *常量的列表,請參閱Soap constants