PHP SoapClient 解決多個namespace的問題。
如果使用SoapClient呼叫遠端wsdl的方法的時候,需要寫傳入引數,通常是一個array, 然後呼叫方法名稱就可以了:
$client = new SoapClient($wsUrl, array('soap_version'=>SOAP_1_2,'cache_wsdl'=>WSDL_CACHE_NONE,'exception'=>true,'trace'=>1));
$client->__soapCall(method_name, $param_array);
如果需要新增namespace, SoapClient 可以在定義的時候增加一個 ‘uri’ 的選項,如下
$client = new SoapClient($wsUrl, array('soap_version'=>SOAP_1_2,‘uri' => 'http://abc/namespace', 'cache_wsdl'=>WSDL_CACHE_NONE,'exception'=>true,'trace'=>1));
但是如果是兩個以上不同的namespace, 就不好添加了。確少namespace呼叫soap請求時候,會報安全錯誤:BIP3113E: Exception detected in message flow...
解決辦法是繼承SoapClient類,過載其__doRequest 方法,修改方法的傳入引數$request, 新增缺失的namespace,然後呼叫就可以成功了。
附加例子:
class MySoapClient extends SoapClient{
function __doRequest($request, $location, $action, $version, $one_way=0){
$newRequest = $request;
$newRequest = str_replace('xmlns:ns1="http://abc.com"', 'xmlns:ns1="http://abc.com" xmlns:web1="http://csdn.com"', $newRequest);
$newRequest = str_replace('<Location>', '<web1:Location>', $newRequest);
$newRequest = str_replace('</Location>', '</web1:Location>', $newRequest);
return parent::__doRequest($newRequest, $location, $action, $version);
}
}
在這個例子中添加了一個namespace web1, 記得一定要把相應的標籤也新增此web1和:,修補請求xml格式,使其滿足規範。
呼叫成功!
如果你有更好的辦法,歡迎討論。