SoapClient,php5自帶的,當然,也可以使用nusoap.php這個純php寫的類,該類代碼行數為7K多行,效率上肯定不如SoapClient.
一、尋找WebService來源
WebService可以自己編寫,但是也可以從網絡上去尋找現成的,我用的是www.xmethods.net里的US Zip Validator,它的WSDL文件位置在:http://www.webservicemart.com/uszip.asmx?WSDL,它的作用是根據輸入的ZIP代碼,返回該代碼對應的美國地名,州名,經緯度等.
二、創建SoapClient
第二步就是創建SoapClient,并調用WebService中的方法,并獲得返回值,PHP代碼如下:
- $objSoapClient = new SoapClient("http://www.webservicemart.com/uszip.asmx?WSDL");
- $param=array("ZipCode"=>$zip);
- $out=$objSoapClient->ValidateZip($param);
- $data=$out->ValidateZipResult;
SoapClient的創建有好多方法,我們用的是最標準的(也是最簡單的)WSDL方法,由于查詢ZIP的方法肯定需要一個參數,所以我們必須創建一個數組,用“參數名=>取值”的方式進行賦值.
也許讀者會對這個數組的創建有一定的興趣,比如,我們怎么知道“參數名”應該是“ZipCode”而不是別的什么呢?為什么沒有更多的參數了,而只有一個?OK,這個問題我們稍后解釋,因為這牽涉到WSDL的解讀.
創建好參數后,同樣的,我們調用SoapClient的方法ValidateZip,并傳遞參數進去,對于返回的結果,我們用$data變量取出我們真正感興趣的東西,同樣的,這里也存在方法名稱是如何確定的問題,我們也在稍后介紹.
如果你也使用PhpEd進行PHP的開發和調試,那么從下面的調試窗口截圖中,你可以很清除的看到$data和$out之間的關系.
三、解析數據
上面得到的$data中的數據是標準的XML結構的數據,所以在PHP中,我們需要創建一個XML解析器來對這個數據進行分析,代碼如下:
- $ParsedData=array();
- function startElement($parser, $name, $attribs)
- {
- global $ParsedData;
- echo "<<font color="#0000cc">$name</font>";
- if (count($attribs)) {
- foreach ($attribs as $k => $v)
- {
- $ParsedData[$k]=$v;
- echo " <font color="#009900">$k</font>="<font color="#990000">$v</font>"";
- }
- }
- echo ">";
- }
- function endElement($parser, $name)
- {
- echo "</<font color="#0000cc">$name</font>>";
- }
- $xml_parser= xml_parser_create();
- xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 1);
- xml_set_element_handler($xml_parser, "startElement", "endElement");
- echo "<pre>";
- if (!xml_parse($xml_parser, $data)) {
- die(sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($xml_parser)),
- xml_get_current_line_number($xml_parser)));
- }
- echo "</pre>";
- xml_parser_free($xml_parser);
這里的詳細操作需要參考PHP函數手冊中關于XML函數的那一章,這里不再贅述,一旦數據被解析成功,我們就可以進行進一步的處理,例如下面的代碼就遍歷該數組,然后輸出,代碼如下:
- foreach ($ParsedData as $k=>$v)
- {
- echo $k."=>".$v."<br />";
- }
四、解讀WSDL
上面我們留下了兩個疑問:如何知道一個WebService提供的方法,以及它的參數?所有的答案都在WSDL描述中,對于本文使用的WSDL來說,我們從中截取一段來分析,由于我們是通過Soap進行調用,所以我對完整的WSDL進行了節選,只列出關于Soap調用的部分(反相顯示的部分)
首先我們注意到<wsdl:message name=”ValidateZipSoapIn”>這一節,它指出了在Soap調用中,入口參數要參照ValidateZip,于是我們接著轉到文件上面一點的地方,看ValidateZip方法的定義,代碼如下:
- <s:element name="ValidateZip">
- <s:complexType>
- <s:sequence>
- <s:element minOccurs="0" maxOccurs="1" name="ZipCode" type="s:string"/>
- </s:sequence>
- </s:complexType>
- </s:element>
很明顯,ValidateZip要求一個參數,名稱為ZipCode,類型為string.
同樣,我們再看<wsdl:message name=”ValidateZipSoapOut”>這一節,它指出Soap調用的出口參數是ValidateZipResponse,而后者的傳出參數名稱是ValidateZipResult。于是,我們就解釋了前兩節提出的問題:
•怎樣找到要調用的函數?
•怎樣知道函數的參數、類型?
•怎樣得到函數的返回值?
例2,這里我們使用php5自帶的類來操作
我的結構如下:在 webservice 文件夾下有如下三個文件:Personinfo.php,SoapClient.php,SoapServer.php,具體作用可以參照代碼中的注釋,代碼如下:
- <?php
- /**
- * Personinfo.php
- * 此類包含了需要調用的方法
- * @author itbdw
- *
- */
- class Personinfo {
- /**
- * 返回姓名
- * @return unknown_type
- */
- public function getName() {
- return ‘IT不倒翁’;
- }
- /**
- * 返回特定格式的日期
- * @return unknown_type
- */
- public function getTime() {
- return date(‘Y-m-d’);
- }
- }
- <?php
- /**
- * SoapServer.php
- * webservice 服務器端實例
- */
- //包含提供服務的類
- require_once ‘Personinfo.php’;
- //根據實際情況修改下行內容
- $s = new SoapServer(null, array("location" => "http://zby/webservice/SoapServer.php", "uri" => "SoapServer.php"));
- $s->setClass("PersonInfo");
- $s->handle();
- [/php]
- [php]
- <?php
- <?php
- /**
- * SoapClient.php
- * webservice 客戶端實例
- */
- header(‘Content-Type:text/html;charset=utf-8′);
- try {
- //根據實際情況修改下行內容
- $soap = new SoapClient(null, array(‘location’=>’http://zby/webservice/SoapServer.php’, ‘uri’=>’SoapServer.php’));
- echo $soap->getName();
- echo $soap->getTime();
- } catch(SoapFault $e) {
- echo $e->getMessage();
- } catch(Exception $e) {
- echo $e->getMessage();
- }
新聞熱點
疑難解答