1. 程式人生 > >PHP SoapClient 解決多個namespace的問題。

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格式,使其滿足規範。

呼叫成功!

如果你有更好的辦法,歡迎討論。