posts - 241,  comments - 116,  trackbacks - 0
          PHP的SOAP擴展可以用來提供和使用Web services。換句話說,PHP開發者可以利用這個PHP擴展來寫他們自己的Web services,也可以寫一些客戶端來使用給定的Web services。

          PHP5中的這個SOAP擴展目的是為了實現PHP對Web services的支持。與其它實現PHP對Web services的支持的方法不同,SOAP擴展是用C寫的,因此它比其它方法具有速度優勢。

          SOAP擴展支持以下規范。

          * SOAP 1.1
          * SOAP 1.2
          * WSDL 1.1

          SOAP擴展主要用來處理RPC形式的Web services。不過,你也可以使用文本形式的WSDL文件配合WSDL模式的服務端和客戶端。

          這個擴展使用 GNOME XML庫來處理XML。

          擴展中的類
          這個擴展實現了6個類。其中有三個高級的類,它們的方法很有用,它們是 SoapClient,SoapServer和SoapFault。另外三個類除了構造器外沒有其它別的方法,這三個是低級的類,它們是SoapHeader,SoapParam和SoapVar。

          SoapClient類

          這個類用來使用Web services。SoapClient類可以作為給定Web services的客戶端。
          它有兩種操作形式:

          * WSDL 模式
          * Non-WSDL 模式

          在WSDL模式中,構造器可以使用WSDL文件名作為參數,并從WSDL中提取服務所使用的信息。

          non-WSDL模式中使用參數來傳遞要使用的信息。這個類有許多可以用來使用服務的有用的方法。其中SoapClient::__soapCall()是最重要的。這個方法可以用來調用服務中的某個操作。

          SoapServer類

          這個類可以用來提供Web services。 與SoapClient類似,SoapServer也有兩種操作模式:WSDL模式和non-WSDL模式。這兩種模式的意義跟 SoapClient的兩種模式一樣。在WSDL模式中,服務實現了WSDL提供的接口;在non-WSDL模式中,參數被用來管理服務的行為。

          在SoapServer類的眾多方法中,有三個方法比較重要。它們是SoapServer::setClass(),SoapServer::addFunction()和SoapServer::handle()。

          SoapServer::setClass()方法設定用來實現Web Service的類。SoapServer::setClass所設定的類中的所有公共方法將成為Web Services的操作(operation)。

          SoapServer::addFunction()方法用來添加一個或多個作為Web Services操作(operation)的函數。

          SoapServer:: handle()方法指示Web Service腳本開始處理進入的請求。Web Service腳本是用PHP腳本寫的一個或多個SoapServer對象的實例。盡管你可以有不止一個的SoapServer對象,但通常的習慣是一個 腳本只擁有一個SoapServer實例。在調用SoapServer::handle()方法之前,Web Service腳本會使用設置在SoapServer對象實例上的任何信息來處理進入的請求和輸出的相應。


          SoapFault類

          這個類從Exception類繼承而來,可以用來處理錯誤。SoapFault實例可以拋出或獲取Soap錯誤的相關信息并按程序員的請求處理。

          SoapHeader類

          這個類可以用來描述SOAP headers。它只是一個只包含構造器方法的數據容器。

          SoapParam類

          SoapParam也是一個只包含構造器方法的數據容器。這個方法可以用來描述傳遞給Web services操作的參數。在non-WSDL模式中這是一個很有用的類,可以用來傳遞所期望格式的參數信息。

          SoapVar類

          SoapVar也是一個只包含構造器的低級類,與SoapHeader和SoapParam類相似。這個類可以用來給一個Web services操作傳遞編碼參數。這個類對non-WSDL中傳遞類型信息是非常有用的。


          WSDL VS. non-WSDL模式

          Web Services有兩種實現模式:契約先行(Contract first)模式和代碼先行(Code first)模式。

          契約先行模式使用了一個用XML定義的服務接口的WSDL文件。WSDL文件定義了服務必須實現或客戶端必須使用的接口。SoapServer和SoapClient的WSDL模式就基于這個概念。

          在 代碼先行模式中,首先要先寫出實現服務的代碼。然后在大多數情況下,代碼會產生一個契約,換種說法,一個WSDL。接著客戶端在使用服務的時候就可以使用 那個WSDL來獲得服務的接口。盡管如此,PHP5的擴展并沒有從代碼輸出一個WSDL的規定,考慮到這種情況,可以在non-WSDL模式下使用 SoapServer和SoapClient。
          SOAP擴展與Hello World

          這一節介紹如何使用WSDL模式和non-WSDL模式來實現服務和客戶端。相對而言,使用WSDL模式來實現服務和客戶端會比較容易,假定已經有一個定義了接口的WSDL文件。因此這一節會先介紹如何使用WSDL模式實現一個Web Service。

          在這個Hello World例子的服務中有一個被命名為greet的操作。這個操作有一個字符串形式的名字并返回一個字符串形式的greeting。所用到的WSDL如下:

          <wsdl:definitions
              xmlns:impl='http://wso2.org/wsf/php/helloService'
              xmlns:intf='http://wso2.org/wsf/php/helloService'
              xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
              xmlns:wsdlsoap='http://schemas.xmlsoap.org/wsdl/soap/'
              xmlns:xsd='http://www.w3.org/2001/XMLSchema'
              targetNamespace='http://wso2.org/wsf/php/helloService'> 
            <wsdl:types>
              <schema elementFormDefault='qualified'
                  xmlns:impl='http://wso2.org/wsf/php/helloService'
                  xmlns:intf='http://wso2.org/wsf/php/helloService'
                  xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
                  xmlns="http://www.w3.org/2001/XMLSchema"
                  targetNamespace='http://wso2.org/wsf/php/helloService' >
                <element name='greet'>
                  <complexType>
                    <sequence>
                      <element name='name' type='xsd:string' />
                    </sequence>
                  </complexType>
                </element>
                <element name='greetResponse'>
                  <complexType>
                    <sequence>
                      <element name='greetReturn' type='xsd:string' />
                    </sequence>
                  </complexType>
                </element>
              </schema>
            </wsdl:types>
            <wsdl:message name='greetRequest'>
              <wsdl:part name='parameters' element='impl:greet' />
            </wsdl:message>
            <wsdl:message name='greetResponse'>
              <wsdl:part name='parameters' element='impl:greetResponse' />
            </wsdl:message>
            <wsdl:portType name='helloService'>
              <wsdl:operation name='greet'>
                <wsdl:input name='greetRequest' message='impl:greetRequest' />
                <wsdl:output name='greetResponse' message='impl:greetResponse' />
              </wsdl:operation>
            </wsdl:portType>
            <wsdl:binding name='helloServiceSoapBinding' type='impl:helloService'>
              <wsdlsoap:binding transport='http://schemas.xmlsoap.org/soap/http' style='document' />
              <wsdl:operation name='greet'>
                <wsdlsoap:operation soapAction='helloService#greet' />
                <wsdl:input name='greetRequest'>
                  <wsdlsoap:body use='literal' />
                </wsdl:input>
                <wsdl:output name='greetResponse'>
                  <wsdlsoap:body use='literal' />
                </wsdl:output>
              </wsdl:operation>
            </wsdl:binding>
            <wsdl:service name='helloService'>
              <wsdl:port binding='impl:helloServiceSoapBinding' name='helloService'>
                <wsdlsoap:address location='http://localhost/hello/hello_service_wsdl.php' />
              </wsdl:port>
            </wsdl:service>
          </wsdl:definitions>

          WSDL模式服務

          下面是WSDL模式的服務所使用的SOAP擴展API代碼:

          <?php
          function greet($param) {
              $retval = 'Hello '.$param->name;
              $result = array('greetReturn' => $retval);
              return $result;
          }

          $server = new SoapServer('hello.wsdl');
          $server->addFunction('greet');
          $server->handle();
          ?>

          在這個服務的實現過程中,函數實現了WSDL所定義的服務操作greet,greet操作有一個WSDL指定的參數,按照greet操作的語義,這個參數是一個用戶的名字。最后handle調用了觸發處理請求的服務對象。


          WSDL模式客戶端

          客戶端代碼如下

          <?php
          try {
              $client = new SoapClient('hello.wsdl');
              $result =  $client->__soapCall('greet', array(array('name' => 'Sam')));
              printf("Result = %s", $result->greetReturn);
          } catch (Exception $e) {
              printf("Message = %s",$e->__toString());
          }
          ?>

          客戶端代碼中,首先創建一個使用WSDL文件作參數的SoapClient實例。接著__soapCall()調用作為參數傳入它的操作,也就是greet和傳入操作的參數。
          請求和響應

          當你將上述的PHP腳本放在你web服務器目錄下的文檔中,并利用WEB瀏覽器或在PHP解析器的命令行調用腳本,客戶端發送一個SOAP請求到服務端腳本,服務端將向客戶端發送一個SOAP響應來響應客戶端的請求。

          下面是客戶端所發送的SOAP請求:

          <?xml version="1.0" encoding="UTF-8"?>  
             <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"                      
                                            xmlns:ns1="http://wso2.org/wsf/php/helloService">   
              <SOAP-ENV:Body>
              <ns1:greet>
              <ns1:name>Sam</ns1:name>
              </ns1:greet>
              </SOAP-ENV:Body>
          </SOAP-ENV:Envelope>

          下面是服務端響應上訴請求而發送的SOAP響應:

          <?xml version="1.0" encoding="UTF-8"?>
             <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                                xmlns:ns1="http://wso2.org/wsf/php/helloService">
                <SOAP-ENV:Body>
                   <ns1:greetResponse>
                      <ns1:greetReturn>Hello Sam</ns1:greetReturn>
                   </ns1:greetResponse>
                </SOAP-ENV:Body>
             </SOAP-ENV:Envelope>

          上面的SOAP消息都是利用WSDL模式的服務端和客戶端來獲取的。也可以利用non-WSDL模式的服務端和客戶端來產生與上面相同的SOAP消息。但是,PHP代碼必須有一點改變。下一節會說明如何使用non-WSDL模式。

          non-WSDL模式服務端

          <?php
          function greet($param) {   
              $retval = 'Hello '.$param;
              return new SoapParam($retval, 'greetReturn');
          }

          $server = new SoapServer(null, array('uri' => 'http://wso2.org/wsf/php/helloService'));

          $server->addFunction('greet');
          $server->handle();
          ?>

          在non -WSDL模式中,想WSDL模式一樣首先實現greet函數的功能,但是函數實現的方式跟WSDL模式稍稍有所不同。在non-WSDL模式中,我們必 須返回一個SoapParam對象作為響應,而不是一個數組。創建服務時,第一個參數設為null,說明沒有提供WSDL;接著傳遞一個選項作為參數,這 個選項參數是服務的URI。最后像WSDL模式一樣調用剩下的方法。

          non-WSDL模式客戶端

          <?php
          try {
              $client = new SoapClient(null,  
              array('location' => 'http://localhost/hello/hello_service_nonwsdl.php',
              'uri' => 'http://wso2.org/wsf/php/helloService'));   
              $result =  $client->__soapCall('greet', array(new SoapParam('Sam', 'name')));    printf("Result = %s", $result);
          } catch (Exception $e) {
              printf("Message = %s",$e->__toString());
          }
          ?>

          在non-WSDL模式中,因為沒有使用WSDL,傳遞了一個包含服務所在位置和服務URI的參數數組作為參數。然后象WSDL模式中一樣調用__soapCall()方法,但是使用了SoapParam類用指定格式打包參數。返回的結果將獲取greet中的響應。

          相關文章:

          PHP代碼的優與劣

          如何用PHP和mysql創建一個ShoutBox

          PHP的文件包含

          PHP的正則表達式處理函數總結分析

          PHP文件上傳實例詳解

          結論
          這篇文章介紹了SOAP擴展,可以在PHP中通過它來提供和使用Web Services。PHP擴展的強項是它的簡單和快速。使用C寫的SOAP擴展來運行服務端和客戶端是非常簡單的。雖然SOAP擴展在處理一些簡單的 Web Services時很有用,但是當用它來處理所有的Web Services時就表現出它的局限性。 WSO WSF/PHP就是為了彌補PHP擴展的缺陷而開發的,它是開源的,可以實現SOAP類似的功能并且支持MTOM,WS-Addressing,WS- Security和WS-RelaiableMessaging。WSO2 WSF/PHP 支持與SOAP擴展類似的API。我們正計劃將API打包起來提供跟SOAP擴展一樣的API,會用C來寫。

          posted on 2008-12-21 09:19 墻頭草 閱讀(3539) 評論(0)  編輯  收藏 所屬分類: PHP

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          人人游戲網 軟件開發網 貨運專家
          主站蜘蛛池模板: 集安市| 湟源县| 永年县| 彰化县| 广安市| 古交市| 东乌珠穆沁旗| 银川市| 武清区| 富川| 东源县| 章丘市| 娄底市| 大余县| 同江市| 紫阳县| 东方市| 泉州市| 乌鲁木齐县| 枣阳市| 彰化县| 湘潭县| 大港区| 翁牛特旗| 重庆市| 扶风县| 津南区| 通化县| 肥西县| 河池市| 钟山县| 古蔺县| 南宁市| 滕州市| 福清市| 武乡县| 涡阳县| 广西| 镇远县| 曲麻莱县| 岑溪市|