學習 PHP SOAP 延伸模組的一些筆記

來源:互聯網
上載者:User
對 SOAP 的相關學習就先告此一段落,這是最後一篇文章用來記錄下學習過程中的一些筆記和心得。

前面三篇文章分別是:

  • 《SOAP 介紹》

  • 《SOAP Web 服務介紹》

  • 《PHP SOAP 延伸模組的使用》

  • 如何理解

    因為 SOAP Web 服務是基於 HTTP 協議的,發出一個 SOAP 訊息請求,實際上利用 HTTP 動詞中的 POST,然後把 SOAP 訊息放置在 HTTP body 裡面發送。簡單來說就是:每調用一次 SOAP 服務,就是發送一條 POST 請求。

    下面是一次請求介面所發送的內容:

    POST /webservices/qqOnlineWebService.asmx HTTP/1.1Host: www.webxml.com.cnConnection: Keep-AliveUser-Agent: PHP-SOAP/5.4.29Content-Type: application/soap+xml; charset=utf-8; action="http://WebXml.com.cn/qqCheckOnline"Content-Length: 247                        8698053            

    我們可以看到,一次 SOAP 請求,實際上就是向伺服器端發送了一個 POST 請求。而發送的內容正是 SOAP 訊息(它表明你本次調用的介面方法以及參數等等)。

    這個 POST 請求,有一些特點,比如:它發送的內容類型為:application/soap+xml,使用者代理程式為 PHP-SOAP/5.4.29 ,其他特點自己觀察,不多說。

    SOAP 延伸模組的作用

    實際上,既然我們知道請求一次介面只是發送一次 POST 請求,那麼我們完全可以使用一些工具或 PHP 本身內建的一些庫(比如 curl、fsockopen)類比發送 POST 請求,而不需要使用 PHP 的 SOAP 延伸模組。對,沒錯!在 PHP 還沒有提供 SOAP 延伸模組前,的確很多人也是這樣做的。

    那幹嘛要用 SOAP 延伸模組呢? 因為它官網的唄,因為它用 C 語言寫的,速度杠杠的,而且封裝得很好用,也不需要自己編寫繁瑣的 XML 代碼了,所以就用它。

    換句話說,實際上 SOAP 延伸模組就是一個更好用,速度更快,專門用於處理 SOAP 服務的 HTTP 封裝庫,沒有什麼很深奧的東西。

    使用方法

    PHP 的協助手冊,有關於 SOAP 延伸模組的詳細說明文檔,已經對如何使用說得很清楚了,特別手冊後面的一些使用者的評論和貢獻的程式碼片段,基本上可以解決你大部分的問題。下面記錄一下自己在開發過程中遇到的一些問題,以及解決的方法和一些需要注意的地方。

    WSDL 和 non-WSDL

    現在基本上所有 SOAP Web 服務都提供 WSDL 介面描述檔案,所以 non-WSDL 這種模式基本上不用考慮。

    關於 SOAP 版本

    PHP SOAP 延伸模組同時支援 SOAP 1.1 和 SOAP 1.2 兩個版本。一般來說,現在的介面基本上也同時支援這兩個 SOAP 協議版本進行通訊,那麼在這種情況下,當然是採用高版本的 SOAP 1.2 了。實際上,無論你是使用哪個版本,如果你是使用 SOAP 延伸模組來調用服務的話,在使用該擴充過程中沒有任何區別,對你來說都是一樣的。唯一需要你去做的是在 SoapCient 進行初始化時,把 soap_version 設定為 SOAP_1_1 或 SOAP_1_2 即可,就像下面這樣:

    // SOAP 1.1 $client = new SoapClient($wsdl, [    'soap_version' => SOAP_1_1]);// SOAP 1.2$client = new SoapClient($wsdl, [    'soap_version' => SOAP_1_2]);

    SoapParam 和 SoapVar

    上面已經說了,現在的服務基本上都提供 WSDL 描述檔案,如果是這樣的話,這兩個類 SoapParam 和 SoapVar 你基本上可以不用管,因為 SOAP 之所以提供這兩個類,主要還是為了 PHP SOAP 延伸模組能夠去使用一些沒有 WSDL 描述檔案的服務,當然這種情況基本上已經不存在了。

    關於 __soapCall 方法

    該方法也一樣,一般都它只會用於 non-WSDL 模式下,因為在 WSDL 模式下,完全可以把你需要調用的方法作為 SoapClient 對象的一個方法進行調用。不過,如果調用方法的 uri 與 預設的 uri 不一樣時,又或者調用該方法時,你必須為它帶上一個 SOAP Header 時,就需要使用 __soapCall 方法了。下面是摘自官方手冊的一段話:

    This is a low level API function that is used to make a SOAP call. Usually, in WSDL mode, SOAP functions can be called as methods of the SoapClient object. This method is useful in non-WSDL mode when soapaction is unknown, uri differs from the default or when sending and/or receiving SOAP Headers.

    __soapCall 在使用上與通過方法名直接調用的方式有一些區別。下面我們來看看幾個例子。同樣的,我們還是使用一個網路上可以免費使用的 SOAP 服務配合我們,該服務的主要作用是通過 QQ 號來查詢該使用者的線上狀態。服務地址

    下面是請求該服務時,應該發送的 SOAP 訊息:

                            string            

    通過方法名調用該介面:

     SOAP_1_2]);$client->qqCheckOnline([    'qqCode' => 8698053]));

    使用 __soapCall 方法調用該介面:

     SOAP_1_2]);$client->__soapCall('qqCheckOnline', [    ['qqCode' => 8698053]]);

    重點關注兩種調用方式時,參數的不一樣。通過方法名直接調用的方式,參數是一維數組,而通過 __soapCall 方法調用時,參數是二維數組,這是它們之間的區別之一。

    還有第二個區別,就是 __soapCall 方法可以在調用介面時,添加額外的 SOAP Header,比如這樣:

    $wsdl = 'http://www.example.com/service.asmx?wsdl';$client = new SoapClient($wsdl, [    'soap_version' => SOAP_1_2]);$auth = ['sAuthenticate' => 'ab3cde34f5r4545g'];$namespace = 'http://www.example.com';$header = new SoapHeader($namespace, 'AuthenHeader', $auth, false);$client->__soapCall("SomeFunction", $parameters, null, $header);

    雖然 SoapClient 也有 __setSoapHeaders 方法,但是它會給該執行個體的所有方法都添加上 SOAP Header,如果存在有些方法需要 SOAP Header 而有些又不需要的話,那麼就必須使用 __soapCall 方法,針對某個方法來添加 SOAP Header 了。

    關於命名空間(namespace)

    實際上,在 WSDL 模式下,如果不需要發送 SOAP Header 的話,那麼 namespace 是用不上的,因為 namespace 實際上已經在 WSDL 檔案中有所描述了,PHP 的 SOAP 延伸模組會自動把它從 WSDL 檔案中解析出來,用於構造 SOAP 請求。如果 SOAP 訊息中,需要添加 SOAP Header 的話,那麼必須提供 namespace。舉個例子:

    比如說,有一個服務它需要你發送的 SOAP 訊息中必須有 SOAP Header,像下面一樣:

                            string                                    int            

    下面是構造該 SOAP 請求的代碼:

     SOAP_1_2]);$auth = ['sAuthenticate' => 'ab3cde34f5r4545g'];$namespace = 'http://www.example.com';$header = new SoapHeader($namespace, 'AuthenHeader', $auth, false);$client->__setSoapHeaders($header);    $response = $client->GetUserInfoById([    'UserID' => 100]);

    可以看到,使用 SoapHeader 來構建一個 SOAP Header 時,必須提供 namespace,而且是正確的命名空間。

    其實,構造一個 SOAP Header 的方法不止這一種寫法,還有其他寫法,比如你還可以這樣構造與上面一樣的 SOAP 訊息:

    sAuthenticate = $auth;    }}$wsdl = 'http://www.example.com/service.asmx?wsdl';$client = new SoapClient($wsdl, [     'soap_version' => SOAP_1_2 ]);$auth = 'ab3cde34f5r4545g';$namespace = 'http://www.example.com';$authenHeader = new AuthenHeader($auth);$header = new SoapHeader($namespace, 'AuthenHeader', $authenHeader, false);$client->__setSoapHeaders($header);$response = $client->GetUserInfoById([     'UserID' => 100 ]);

    關於 SoapHeader 其他更多的用法,推薦翻閱 PHP 手冊中的 SOAP 章節。

    關於 SoapFault

    服務端在處理用戶端請求發生錯誤時,將會拋出 SoapFault 異常。對於 SOAP 延伸模組中,哪些方法可能會拋出異常可以查看手冊。一旦發生了異常,我們都應該捕捉它們,並妥善處理。像下面這樣:

    try {    $client = new SoapClient($wsdl, [        'trace' => true,        'soap_version' => SOAP_1_2    ]);    .....} catch(SoapFault $e) {    //在這裡處理異常}

    getLastRequest 和 getLastResponse

    這兩個方法可以查看最近一次請求和響應的內容,這兩個方法對於調試很有協助。當然,這兩個方法只有在 SoapClient 執行個體化時,trace 參數設定為 true 才會生效。比如像這樣:

     true,    'soap_version' => SOAP_1_2]);$client->qqCheckOnline([    'qqCode' => 8698053]));echo $client->__getLastRequest();echo $client->__getLastResponse();

    getLastRequest() 輸出的內容:

                            8698053            

    getLastResponse() 輸出的內容:

                            Y            

    SoapUI 調試工具

    在調試 SOAP 服務介面時,我們可以使用功能強大的 SoapUI 工具,可以很方便地調試介面。

    總結

    上面都是自己在學習 PHP SOAP 延伸模組時的一些零散的筆記,如果有不對的地方,希望大家指出,謝謝。(本文已存檔 GitHub)

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.