茫茫網海中的冷日
         
茫茫網海中的冷日
發生過的事,不可能遺忘,只是想不起來而已!
 恭喜您是本站第 1729034 位訪客!  登入  | 註冊
主選單

Google 自訂搜尋

Goole 廣告

隨機相片
IMG_60D_00051.jpg

授權條款

使用者登入
使用者名稱:

密碼:


忘了密碼?

現在就註冊!

PHP特區 : [轉貼]PHP and Web Services 學習筆記

發表者 討論內容
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]PHP and Web Services 學習筆記
PHP and Web Services 學習筆記
作者:edong www.edong.org (2005-04-13 11:54:58)

全文分為三個部分:
概述。PHP進行Web Services開發的優點,在Unix系統上安裝配置PHP
在PHP中使用SOAP。NuSOAP 工具包,NuSOAP的高級Web Service功能,如HTTP代理,SOAP over HTTPS,document style messaging。還將討論如何解決一些PHP Web Services編程將會遇到的問題,如安全問題,語言到數據類型的映射
PHP中的XML-RPC。XML-RPC的特性,XML-RPC與SOAP的對比,然後使用Useful, Inc.實現來創建XML-RPC的客戶端和服務器程序
下面是第一部分。

Section 1. 概述
PHP 中已經通過綁定了Expat parser內置了XML支持,額外的還可以使用一些擴展程序(extension),如domxml(通過使用libxml庫提供DOM, Xpath, Xlink支持),xslt(為複雜的第三方XSLT庫如Sablotron和libxslt提供的外包程序)。

另一個對 Web Service 開發有用的PHP擴展程序是CURL(Client URL Library)。CURL允許你通過不同的協議,如HTTP, HTTPS, FTP, telnet, LDAP來通訊,其中的HTTPS對Web Services與服務器進行安全連接尤其有用。

SOAP vs XML-RPC 優缺點:
強大的類型擴展 (SOAP)
用戶自定義字符集,如US-ASCII, UTF-8, UTF-16 (SOAP)
Specifies recipient [指定容器?] (SOAP)
容器遇到無法理解的報文則失敗 (SOAP)
易於使用 (XML-RPC)
設計簡單 (XML-RPC)

配置PHP:
Apache: 為了讓PHP作為Apache的模塊方式運行,使用 --with-apxs選項編譯,如 --with-apxs=/www/bin/apxs。[我現在使用的Apache2, 我編譯的PHP使用的選項是--with-apxs2=/usr/sbin/apxs]
DOMXML: 可選功能,對解析XML文檔十分有幫助。需要預先安裝好libxml庫(版本>=2.4.2),編譯時使用 --with-dom=DIR 選項(缺省DIR為/usr)
http://www.xmlsoft.org/downloads.html
libxml 2.6.4 - sources - 2.52 MB

XSLT: 可選功能,對轉換XML資料為其他類型的文檔有幫助。編譯時使用 --enable-xslt --with-xslt-sablot 選項。必須預先安裝Sablotron XSLT庫(http://www.gingerall.com/),(缺省DIR為/usr/lib或者/usr/local/lib)。
Sablotron 1.0.1 - sources - 470 kB

CURL: 如前所述,若提供SSL支持則是必須安裝的。編譯時使用 --with-curl=DIR 選項。也同樣需要預先安裝CURL庫(版本>=7.0.2-beta)。 [我的PHP已經安裝了。CURL Information: libcurl/7.10.7 OpenSSL/0.9.7c zlib/1.1.4]

Section 2. SOAP
NuSOAP介紹:
NuSOAP是一組開源的,用來通過HTTP收發SOAP消息的PHP類,由NuSphere Corporation (http://www.nusphere.com
) 開發。NuSOAP的一個優勢是他不是一個擴展程序,而是純粹用PHP代碼寫的,所以適用範圍比較廣。

安裝配置:
http://dietrich.ganx4.com/nusoap/ 下載,從zip文件中解出nusoap.php文件放到include目錄,在你的腳本前面加上
include('nusoap.php');
就搞定了。

範例:
下面是一個簡單的SOAP client程序: soap_client.php 執行
//simple client
require('nusoap.php');

//要發送的變量
$myString="world";

//parameters must be passed as an array
//變量必須要轉換成數組的形式
$parameters=array($myString);

//創建一個soapclient對象,參數是server的URL
$s=new soapclient('http://www.douzi.org/me/php_ws/soap_server.php');

//調用遠程方法,返回值存放在$result
//返回值為PHP的變量類型,如string, integer, array
$result=$s->call('echoString', $parameters);

//錯誤檢測
if (!$err=$s->getError()) {
echo 'Result: '.$result; //success
} else {
echo 'Error: '.$err;
}

//調試,以下是SOAP請求(request)和回應(response)的報文,包括HTTP頭
echo "<xmp>".$s->request."</xmp>";
echo "<xmp>".$s->response."</xmp>";

?>



相應的server端程序: soap_server.php
//simple server
require('nusoap.php');

//創建一個新的soap_server對象,並註冊允許遠程調用的方法
$s=new soap_server;
$s->register('echoString');
$s->register('echoArray');

/*
[文章中說:
缺少了註冊這一步,任何PHP函數都將可以進行遠程調用,這將是一個極大的安全隱患。
但是我嘗試過註冊是必須的。
而且只有將結果return的函數才能直接聲明為遠程方法,比如echo()就不行,而strtolower()就可以。]
*/

function echoString($inputString) {
//類性檢查
if(is_string($inputString)) {
return "Hello, ".$inputString;
} else {
//soap_fault類用於產生錯誤信息
return new soap_fault('client', '', 'The parameter to this service must be a string.');
//soap_fault(faultcode, faultactor, faultstring, faultdetail);
//上面是錯誤處理類的構造函數的格式
//faultcode 必須值。可以設置為client或server,來表明錯誤發生在哪一端。
//faultactor 在NuSOAP中尚未實現。
//faultstring 錯誤信息。
//faultdetail 詳細錯誤信息。你可以使用XML標記。

//除了構造函數外,soap_fault類還有一個serialize()方法
//它將錯誤信息序列化,然後返回一個完整的SOAP報文,範例:
/*
$fault = new soap_fault('client', '', 'The inputString parameter must not be empty');
echo $fault->serialize();
*/
}
}

//演示數組類型的使用
function echoArray($inputString) {
return $inputString[0]."+".$inputString[1];

}

//最後一步是把所有的收到的post數據都傳遞給SOAP server的service方法。它將處理請求,並調用相應的函數。
$s->service($HTTP_RAW_POST_DATA);
?>


複雜數據類型的使用:
數組。以下是生成的SOAP的Body部分代碼:
string1
string2


生成復合數據類型(compound types samples),使用soapval。以下是生成的SOAP的Body部分代碼:
123 Freezing Lane
Nome
Alaska
12345

1234567890
0987654321


程序範例: soapval.php 執行
//soapval: general compound types samples
include('nusoap.php');

$address=array(
'street'=>'123 Freezing Lane',
'city'=>'Nome',
'state'=>'Alaska',
'zip'=>12345,
'phonenumbers'=>array('home'=>'1234567890', 'mobile'=>'0987654321')
);

$s=new soapval('myAddress', 'address', $address, '', 'http://myNamespace.com');

print "<xmp>".$s->serialize()."</xmp>";

?>


WSDL
WSDL是一種用於描述Web Service的XML語言。它是一種機讀格式,把所有的訪問服務所必須的信息提供給Web Service客戶端。NuSOAP專門提供一個類進行WDSL文件的解析,並且從中提取信息。soapclient對像使用wsdl類來減輕開發者調用服務的難度。通過WSDL信息的幫助來創建報文,程序員僅僅需要知道操作的名字和參數就能調用它。

通過NuSOAP使用WSDL提供以下幾點優點:
所有的服務元文件,如命名空間(namespaces),endpoint URLs,參數名(parameter names)等等都可以直接從WSDL文件獲得,這樣就允許客戶端動態的適應服務器端的變化。因為從服務器隨時可以獲得,所以這些數據不再需要在用戶腳本中使用硬性編碼。
它允許我們使用soap_proxy類。這個類派生自soapclient類,增加了WDSL文件中詳細列出的操作所對應的方法。現在用戶通過它可以直接調用這些方法。
soapclient 類包含一個getProxy()方法,它返回一個soap_proxy類的一個對象。soap_proxy類派生自soapclient類,增加了對應於 WSDL文檔中定義的操作的方法,並且允許用戶調用一個endpoint的遠程方法。這僅僅適用於soapclient對像用WDSL文件初始化的情況。優點是易於用戶使用,缺點是性能--PHP中創建對象是耗時的--且不為功利目的服務(and this functionality serves no utilitarian purpose)。

範例: wsdl.php 執行
//wsdl的一個簡單演示文件
include('nusoap.php');

//SOAP源為一個提供明星生卒年月的service
//首先我們創建一個soapclient對象,把WSDL文件的URL傳遞給構造函數,
//之後還要使用第二個參數以便使client知道我們傳遞過來的是WSDL,而不是SOAP endpoint。
$s=new soapclient('http://www.abundanttech.com/webservices/deadoralive/deadoralive.wsdl', 'wsdl');

//生成proxy類
$p=$s->getProxy();

//調用遠程函數
$sq=$p->getTodaysBirthdays();

if (!$err=$p->getError()) {
print_r($sq);
} else {
print "ERROR: $err";
}

print 'REQUEST:<xmp>'.$p->request.'</xmp>';
print 'RESPONSE:<xmp>'.str_replace('><', ">\n<", $p->response).'</xmp>';

?>


(http://www.fanqiang.com)

原文鏈接:http://www.edong.org/main/content/view/442/38/1/1/


原文出處:PHP and Web Services 学习笔记 - fanqiang.com
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]實戰WebService I: XML-PRC篇(基於php)
實戰WebService I: XML-PRC篇(基於php)

XML-RPC是一種簡單的,輕量級的通過HTTP協議進行RPC通信的規範。一個XML-RPC消息就是一個請求體為XML的HTTP-POST請求,被調用的方法在服務器端執行並將執行結果以XML格式編碼後返回。 XML-RPC 和SOAP是創建web services的兩種標準協議。XML-RPC是出現較早的(也比較簡單),而SOAP較新,也比較複雜。Microsoft的.NET就是基於 SOAP,而很多流行的WEB程序,如Frontier和blogger,則提供XML-RPC接口。

PHP通過xmlrpc擴展提供SOAP和XML-RPC的訪問途徑。xmlrpc基於xmlrpc-epi項目(更多信息請查看http://xmlrpc-epi.sourceforge.net)。xmlrpc擴展默認是不可用的,你需要在編譯PHP時加上–with-xmlrpc選項來啟用該擴展。

以下是通過ethereal抓到的一個典型的XML-RPC調用包(為便於閱讀,進行了格式化):

1. 請求報文格式

POST /xmlrpc HTTP/1.1
Content-Type: text/xml
User-Agent: Apache XML RPC 3.0 (Jakarta Commons httpclient Transport)
Host: 135.252.156.147:8080
Content-Length: 260
<?xml version="1.0" encoding="UTF-8"?>
<methodCall xmlns:ex="http://ws.apache.org/xmlrpc/namespaces/extensions">
      <methodName>Calculator.add</methodName>
      <params>
            <param>
                  <value>
                        <i4>2</i4>
                  </value>
            </param>
            <param>
                  <value>
                        <i4>3</i4>
                  </value>
            </param>
      </params>
</methodCall>


2. 報文返回格式

而對應的返回數據包為:

HTTP/1.1 200 OK
Server: Apache XML-RPC 1.0
Connection: close
Content-Type: text/xml
Content-Length: 189
<?xml version="1.0" encoding="UTF-8"?>
<methodResponse xmlns:ex="http://ws.apache.org/xmlrpc/namespaces/extensions">
      <params>
            <param>
                  <value>
                        <i4>5</i4>
                  </value>
            </param>
      </params>
</methodResponse>

其格式很簡單,幾乎是不言自明的,分別用methodCall和methodResponse標籤標識發送給Server的調用請求和Server的返回結果,請求方法的名稱用methodName標識,參數用params和param標識,而參數的類型標籤則如下表所示:

示例

XML-RPC需要PECL擴展支持,在Windows下,對應的dll文件是:php_xmlrpc.dll
寫一個XML-RPC服務器

<?php
 //該函數暴露給客名端的名稱為「multiply( )」
 function times ($method, $args) {
   return $args[0] * $args[1];
 }
 $request = $HTTP_RAW_POST_DATA;
 if (!$request) $request_xml = $HTTP_POST_VARS['xml'];

 $server = xmlrpc_server_create(  );

 if (!$server) die("Couldn't create server");
 xmlrpc_server_register_method($server, 'multiply', 'times');
 $options = array('output_type' => 'xml', 'version' => 'auto');
 echo xmlrpc_server_call_method($server, $request, null, $options);

 xmlrpc_server_destroy($server);
?>

客戶端

XML-RPC客戶端的主要工作是發出HTTP請求和解析服務器發回的響應。PHP所帶的xmlrpc擴展可以將XML-RPC請求用XML編碼,但它不知道如何發送HTTP請求。如果要具有這樣的功能,可以從http://xmlrpc-epi.sourceforge.net下載xmlrpc-epi程序包,然後安裝其中的sample/utils/utils.php文件。該文件包含一個可以執行HTTP請求的函數。

<?php
  require_once('utils.php');
  $options = array('output_type' => 'xml', 'version' => 'xmlrpc');
  $result = xu_rpc_http_concise(
    array(method  => 'multiply',
          args     => array(9, 6),
          host     => 'localhost',
          uri      => '/php/rpc_webservice/xmlrpc_server.php',
          options => $options)
  );
  //echo $result;
  echo "9 * 6 is $result";
?>

還有一些XML-RPC特性這裡未提及,如XML-RPC的數據類型並不總是與PHP的數據類型精確對應,但可以將這些值編碼成特殊的數據類型而不採用 xmlrpc擴展通過最佳猜測選擇的數據類型。當然,PHP的xmlrpc擴展的一些特性我們也沒有介紹,如SOAP錯誤。想知道全部細節,請查看http://www.php.net , 上面有xmlrpc擴展的詳細文檔。


原文出處:实战WebService I: XML-PRC篇(基于php) - 百草园 - JavaEye技术网站
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]實戰WebService II: SOAP篇(基於php)
實戰WebService II: SOAP篇(基於php)

概述(SOAP和XML-PRC比較)

在Web服務發展的初期,XML格式化消息的第一個主要用途是,應用於XML-RPC協議,其中RPC代表遠程過程調用。在XML遠程過程調用 (XML-RPC)中,客戶端發送一條特定消息,該消息中必須包括名稱、運行服務的程序以及輸入參數。

XML-RPC只能使用有限的數據類型種類和一些簡單的數據結構。人們認為這個協議還不夠強大,於是就出現了SOAP——其最初的定義是簡單對像訪問協議。之後,大家逐漸意識到SOAP其實並不簡單,而且也不需要必須使用面向對像語言,所以,現在人們只是沿用SOAP這個名稱而已。

XML-RPC只有簡單的數據類型集,取而代之,SOAP是通過利用XML Schema的不斷發展來定義數據類型的。同時,SOAP也能夠利用XML 命名空間,這是XML-RPC所不需要的。如此一來,SOAP消息的開頭部分就可以是任何類型的XML命名空間聲明,其代價是在系統之間增加了更多的複雜性和不兼容性。

隨著計算機行業的覺醒,人們發現了基於XML的Web服務的商業潛力,於是,各家公司開始不斷地發掘想法、觀點、論據以及標準化嘗試。W3C曾經設法以「Web服務活動」的名義來組織成果展,其中也包括實際做出SOAP的XML協議工作組(XML Protocol Working Group)。與Web服務有關的標準化成果(從某種程度上說與SOAP相關或者依賴於SOAP)的數量已經倍增了到了令人驚訝的程度。

最初,SOAP是作為XML-RPC的擴展而發展起來的,它主要強調的是,通過從WSDL文件中所獲得的方法和變量名來進行遠程過程調用。現在,通過不斷進步,人們發現了更多的使用SOAP的方式,而不僅僅是採用「文件」方式——基本上是使用一個SOAP信封來傳送XML格式化文件。無論如何,要掌握SOAP,瞭解WSDL所扮演的角色是最根本的。

SOAP數據包結構解析

SOAP的消息被稱為一個SOAP Envelope,包括SOAP Header和SOAP Body。其中,SOAP Header可以方便的插入各種其它消息來擴充Web Service的功能,比如Security(採用證書訪問Web Service),SOAP Body則是具體的消息正文,也就是Marshall後的信息。

SOAP調用的時候,也就是向一個URL(比如 http://api.google.com/search/beta2 )發送HTTP Post報文(根據SOAP規範,HTTP Get報文也可被支持),調用方法的名字在HTTP Request Header SOAP-Action中給出,接下來就是SOAP Envelope了。服務端接到請求,執行計算,將返回結果Marshall成XML,用HTTP返回給客戶端。

以下[是移動MISC接入]Wap1.6業務訂購數據包樣例
MISC1.6的業務訂購關係同步的請求包
<?xml version="1.0" encoding="utf-8" ?>
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                   xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Header>
    <TransactionID xmlns="http://10.1.2.122/misc/dsmp.xsd">
00110100037392</TransactionID>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <SyncOrderRelationReq xmlns="http://10.1.2.122/misc/dsmp.xsd">
      <Version>1.5.0</Version>
      <MsgType>SyncOrderRelationReq</MsgType>
      <Send_Address>
        <DeviceType>0</DeviceType>
        <DeviceID>0011</DeviceID>
      </Send_Address>
      <Dest_Address>
        <DeviceType>400</DeviceType>
        <DeviceID>0</DeviceID>
      </Dest_Address>
      <FeeUser_ID>
        <UserIDType>2</UserIDType>
        <MSISDN />
        <PseudoCode>00116000000286</PseudoCode>
      </FeeUser_ID>
      <DestUser_ID>
        <UserIDType>2</UserIDType>
        <MSISDN />
        <PseudoCode>00116000000286</PseudoCode>
      </DestUser_ID>
      <LinkID>SP</LinkID>
      <ActionID>1</ActionID>
      <ActionReasonID>1</ActionReasonID>
      <SPID>919102</SPID>
      <SPServiceID>0000000064</SPServiceID>
      <AccessMode>2</AccessMode>
      <FeatureStr />
    </SyncOrderRelationReq>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

MISC1.6的業務訂購關係同步的響應包:

<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:xsd="http://www.w3.org/2001/XMLSchema"
         xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
         xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Header>
    <TransactionID xmlns="http://www.monternet.com/dsmp/schemas/">
00110100037392</TransactionID>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <SyncOrderRelationResp xmlns="http://www.monternet.com/dsmp/schemas/">
      <Version>1.5.0</Version>
      <MsgType>SyncOrderRelationResp</MsgType>
      <hRet>0</hRet>
    </SyncOrderRelationResp>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>


實戰SOAPI

現在做SOAP開發一般有三種方式選擇
* PEAR自帶的soap擴展,
* PHP自帶的SOAP擴展,
* NuSOAP(純PHP,似乎已經過時)
註:還有WSO2.org(關於WSO2.org可以考慮嘗試一下)

PHP 5 中新增了內置的 SOAP 擴展,我們稱之為 ext/soap。它是作為 PHP 的一部分提供的,因此不需要下載、安裝和管理單獨的包。這是第一個用 C 而不是 PHP 為 PHP 編寫的 SOAP 實現,因此作者聲稱它的速度要快得多。

因為新的擴展是 PHP 的完整組成部分之一,相關文檔包含在 PHP 手冊的 Function Reference 部分(php_soap.dll)。

SOAP 參考是以一個重要的免責聲明開始的:

警告:該擴展是試驗性的(EXPERIMENTAL)。本擴展的行為,包括關於本擴展的函數名和其他內容,在以後的 PHP 版本中隨時可能改變,不另行通知。使用該擴展的風險自負。

警告看起來有點讓人擔心,但實際上這個擴展似乎得到了很好的支持。和任何新代碼一樣,該擴展也存在缺陷,但是報告的問題通常很快就能得到修正。在 PHP 站點上可以看到缺陷列表。我們估計,在將來的 PHP 版本中,該擴展將從試驗性功能轉為主流功能

一個訪問.NET WEB服務的客戶端例子

<?php

$objSoapClient = new SoapClient("http://www.webservicemart.com/uszip.asmx?WSDL");

$param=array("ZipCode"=>'12209');
$out=$objSoapClient->ValidateZip($param);
$data=$out->ValidateZipResult;
echo $data;
?>

運行後輸出

<result code="200"><item zip="12209" state="NY"
latitude ="42.64081" longitude ="-73.7856"/></result>

在實驗的過程當中,使用了一個抓包工具Wireshark來分析報文。Wireshark很不錯,在Filter處設置ip.addr == 208.109.78.12(208.109.78.12 是 www.webservicemart.com 的IP),然後啟動監控,可以分析上述調用過程中HTTP包是什麼樣的。

實戰SOAPII
用PHP建立SOAP服務

建立soap_server.php(虛擬路徑為:http://172.16.0.24/php/soap/soap_server.php)

<?php
/**
* A simple math utility class
* @author John Coggeshall john@zend.com
 */
class math {
  /**
   * Add two integers together
  *
  * @param integer $a The first integer of the addition
  * @param integer $b The second integer of the addition
  * @return integer The sum of the provided integers
   */
  public function add($a, $b) {
    return $a + $b;
  }

 /**
  * Subtract two integers from each other
  *
  * @param integer $a The first integer of the subtraction
  * @param integer $b The second integer of the subtraction
  * @return integer The difference of the provided integers
  */
  public function sub($a, $b) {
    return $a - $b;
  }

 /**
  * Div two integers from each other
  *
  * @param integer $a The first integer of the subtraction
  * @param integer $b The second integer of the subtraction
  * @return double The difference of the provided integers
  */
  public function div($a, $b) {
    if($b == 0) {
      throw new SoapFault(-1, "Cannot divide by zero!");
    }
    return $a / $b;
  }
}
  $server = new SoapServer('math.wsdl', array('soap_version' => SOAP_1_2));
  $server->setClass("math");
  $server->handle();

?>


注意幾點:

1.math類是即將公開的webservice.
2.注$server→setClass,不是$server→addClass

用PHP客戶端訪問剛建立SOAP服務

<?php
  //$client = new SoapClient('http://localhost/php/soap/math.wsdl');
  $client = new SoapClient("http://localhost/php/soap/soap_server.php?WSDL");
  try {
    $result = $client->div(8, 2); // will cause a Soap Fault if divide by zero
    print "The answer is: $result";
  } catch(SoapFault $e) {
    print "Sorry an error was caught executing your request: {$e->getMessage()}";
  }
?>

本質上,http://localhost/php/soap/soap_server.php?WSDL就是要訪問到註釋行所指的wsdl描述文件,所以這個WSDL文件必須事先生成。而對於其他語言如Java則可以動態生成。我目前的學習發現對於php自帶的SOAP擴展要求這個WSDL文件必須事先生成好。

可以用ZendStudio生成靜態的WSDL文件,此時用到math類的phpdoc作為生成WSDL的元數據。 用ZendStudio生成wsdl文件時,必須正確說明web服務目標地址,片斷如下:

...
	<service name="mathService">
		<port name="mathPort" binding="typens:mathBinding">
			<soap:address location="http://localhost/php/soap/soap_server.php"/>
		</port>
	</service>
....


特別注意:我發現調用php webserver的方法和調用.net web服務的方法不一樣。 調用.net service方法必須傳入命名參數;而調用php web服務方法,一定不能傳入命名參數,只能按順序傳入,為什麼?這一點尤其要注意


原文出處:实战WebService II: SOAP篇(基于php) - 百草园 - JavaEye技术网站
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]實戰WebService III: REST篇(基於php)
實戰WebService III: REST篇(基於php)

REST是什麼

REST是英文Representational State Transfer的縮寫,中文翻譯:表述性狀態轉移。

他是由Roy Thomas Fielding博士在他的論文 《Architectural Styles and the Design of Network-based Software Architectures》中提出的一個術語。

REST本身只是為分佈式超媒體系統設計的一種架構風格,而不是標準.
Restful Web Service面向資源,不是面向動作(Action)
REST風格Web Service報文格式
什麼,你一點都不懂我說什麼?那麼先看看Rest基本概念

有效的XML格式都可以說是Rest風格的報文。如YAHOO提供的Restful Web Service的一個例子 : http://api.search.yahoo.com/WebSearchService/V1/webSearch?query=%5C%22XML%20Query%5C%22&appid=YahooDemo
下面是訪問後返回結果片斷

<?xml version="1.0" encoding="UTF-8" ?>
<ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:yahoo:srch"
xsi:schemaLocation="urn:yahoo:srch http://api.search.yahoo.com/WebSearchService/V1/WebSearchResponse.xsd"
type="web" totalResultsAvailable="575000"
totalResultsReturned="10" firstResultPosition="1"
moreSearch="/WebSearchService/V1/webSearch?query=%5C%22XML+Query%5C%22&appid=YahooDemo®ion=us">
  <Result>
    <Title>W3C XML Query (XQuery)</Title>
    <Summary>Language that allows for flexible query facilities to extract data
    from real and virtual documents on the Web.</Summary>
    <Url>http://www.w3.org/XML/Query</Url>
    <ClickUrl>http://uk.wrs.yahoo.com/_ylt=A0Je5Vx_EWpHwV0AkC7dmMwF;
    _ylu=X3oDMTB2cXVjNTM5BGNvbG8DdwRsA1dTMQRwb3MDMQRzZWMDc3IEdnRpZAM-/
    SIG=11fuf4pkj/EXP=1198220031/**http%3A//www.w3.org/XML/Query</ClickUrl>
    <DisplayUrl>www.w3.org/XML/Query</DisplayUrl>
    <ModificationDate>1198051200</ModificationDate>
    <MimeType>text/html</MimeType>
    <Cache>
      <Url>http://uk.wrs.yahoo.com/_ylt=A0Je5Vx_EWpHwV0AkS7dmMwF;
      _ylu=X3oDMTBwOHA5a2tvBGNvbG8DdwRwb3MDMQRzZWMDc3IEdnRpZAM-/
      SIG=16gufb4vc/EXP=1198220031/**http%
      3A//66.218.69.11/search/cache%3Fei=UTF-8%26query=%255C%2522XML%2BQuery%255C%2522%26
      appid=YahooDemo%26u=www.w3.org/XML/Query%26w=%2522xml%2Bquery%2522%26d=DYOEo7XiP-1e%26icp=1%26.intl=us</Url>
      <Size>58502</Size>
    </Cache>
  </Result>
  <Result>
    <Title>XQuery 1.0: An XML Query Language</Title>
    <Summary>Don Chamberlin (XML Query WG), IBM Almaden Research Center,
    via http://www. ... has been developed by the W3C XML Query Working Group,
    which is part of the ...</Summary>
    <Url>http://www.w3.org/TR/xquery/</Url>
    <ClickUrl>http://uk.wrs.yahoo.com/_ylt=A0Je5Vx_EWpHwV0Aky7dmMwF;
    _ylu=X3oDMTB2ZjQ4dDExBGNvbG8DdwRsA1dTMQRwb3MDMgRzZWMDc3IEdnRpZAM-/
    SIG=11g15fbj0/EXP=1198220031/**http%3A//www.w3.org/TR/xquery/</ClickUrl>
    <DisplayUrl>www.w3.org/TR/xquery/</DisplayUrl>
    <ModificationDate>1169193600</ModificationDate>
    <MimeType>text/html</MimeType>
    <Cache>
      <Url>http://uk.wrs.yahoo.com/_ylt=A0Je5Vx_EWpHwV0AlC7dmMwF;
      _ylu=X3oDMTBwZG5hOWwzBGNvbG8DdwRwb3MDMgRzZWMDc3IEdnRpZAM-/SIG=16hn3aelo/EXP=1198220031
      /**http%3A//66.218.69.11/search/cache%3Fei=UTF-8%26query=%255C%2522XML%2BQuery%255C%2522%26
       *      appid=YahooDemo%26u=www.w3.org/TR/xquery/%26w=%2522xml%2Bquery%2522%26d=YBKWrbXiP9TA%26icp=1%26.intl=us</Url>
      <Size>525624</Size>
    </Cache>
  </Result>
....
</ResultSet>
<!-- ws02.search.scd.yahoo.com compressed/chunked Wed Dec 19 22:53:51 PST 2007 -->


下面是我使用CakePhp(一個PHP框架)在本機構建了一個rest服務,
當訪問http://localhost/hostel/rest/countries/listing 時,得到下面的XML

<?xml version="1.0" encoding="utf-8" ?>
<rsp stat="ok">
  <countries type='array'>
    <country type='struct'>
      <id>830</id>
      <title>United States</title>
    </country>
    <country type='struct'>
      <id>831</id>
      <title>Canada</title>
    </country>
    ....
  </countries>
</rsp>

再次強調:Restful Web Service是一種風格,XML是任意的。不過最近好像出了WADL規範應用於Rest,好像WSDL規範SOAP一樣,有空可以研究一下。
訪問Restful Web Service(客戶端代碼)

再次確認,你理解了Restful?---風格,是一種風格,所以:
Restful webservice客戶端像解析一般的xml一樣,獲得Restful Web Service返回的XML流,用DOM/SAX/SimpleXML解析它均可。

這裡使用php的SimpleXML API操縱前面提到Yahoo服務。

SimpleXML 擴展適合於操縱不很複雜或者嵌套不太深並且沒有混合內容的 XML 文檔。SimpleXML 比 DOM 更容易編碼,就像名稱所暗示的那樣。如果處理的文檔結構已知,就更加直觀。libXML2 架構的互操作性大大增強了 DOM 和 SimpleXML 的靈活性,能夠隨意在 DOM 和 SimpleXML 之間交換導入格式。

下面的代碼使用 SimpleXML 擴展解析查詢結果。

<?php
  //This query does a search for any Web pages relevant to "XML Query"
  $query = "http://api.search.yahoo.com/WebSearchService/V1/webSearch?"."query=%5C%22XML%20Query%5C%22&appid=YahooDemo";
  $xml = simplexml_load_file($query);
  // Load up the root element attributes
  foreach($xml->attributes() as $name=>$attr) {
   $res[$name]=$attr;
  }
  //Use one of those "informational" elements to display the total
  //number of results for the query.
  echo "<p>The query returns ".$res["totalResultsAvailable"]." total results The first 10 are as follows:</p>";
  //Unlike with DOM, where we loaded the entire document into the result object,
  // with SimpleXML, we get back an object in thefirst place,
  // so we can just use the number of results returned to loop through the Result members.
  for($i=0; $i<$res['totalResultsReturned']; $i++) {
   //The object represents each piece of data as a member variable
   //rather than an array element, so the syntax is a little bit
   //different from the DOM version.
   $thisResult = $xml->Result[$i];
   echo "<a href='".$thisResult->ClickUrl."'><b>".
   $thisResult->Title."</b></a>: ";
   echo $thisResult->Summary;
   echo "<br /><br />";
  }
?>

輸出結果類似如下HTML效果:

寫一個自己的Restful Web Service

別嫌我囉嗦,再一次地,前面說過:Restful Web Service是任意的有效的XML。所以使用php/jsp等服務器端技術,不需要任何框架都可以生成你想要得XML流。如此說來:這個Restful Web Service例子也沒什麼好寫的嘍

CakePHP是一個基於PHP的web框架,提供了更好的輸出Restful風格的Web Service的能力。Y有興趣請看官方Cakephp文檔


原文出處:实战WebService III: REST篇(基于php) - 百草园 - JavaEye技术网站
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]使用php提供Web service
上回提到了如何使用php去呼叫別人提供的web service
這回我們來看看如何提供一個web service給別人吧

server.php

<?php
class HelloServise
{
 //$__dispatch_map 用來定義這個hello function輸出以及輸入的參數型態
 var $__dispatch_map = array();
 function HelloServise()
 {
   //我們在constructor這邊指定好Hello這個函數Input的參數只有一個
   //名稱叫input型態是string
  //傳回值是一個string型態的值
   $this->__dispatch_map['Hello'] =
   array('in' => array('input' => 'string'),
         'out' => array('output' => 'string'),
       );
 }
 function Hello($input)
 {
  return "Hello:[$input]";
 }
}
require_once 'SOAP/Server.php';
require_once 'SOAP/Disco.php';
//產生一個SOAP Server物件
$server = new SOAP_Server;
//產生一個我們要提供的web service物件
$Hello = new HelloServise();
//向SOAP Server註冊我們提供的Web Service名稱叫HelloService
$server->addObjectMap($Hello,'urn:HelloService');
//因為我們取得Client送過來的xml是用POST方式
//所以我們檢查如果送過來的資料是用POST送過來的
//就直接交給SOAP Server去做處理
if ($_SERVER['REQUEST_METHOD']=='POST')
 $server->service($HTTP_RAW_POST_DATA);
else
{
 //產生一個discover物件
 //用來產生wsdl
 $disco = new SOAP_DISCO_Server($server,'HelloServise');
 //設定輸出文件為xml格式
 header("Content-type: text/xml");
 //如果client呼叫的時候是xxx.php?wsdl
 //就呼叫getWSDL()傳回wsdl格式的XML
 //否則就送回正確取得wsdl方式的XML
 if($_SERVER['QUERY_STRING']=='wsdl') echo $disco->getWSDL();
 else  echo $disco->getDISCO();
}
?>

我們來測試一下剛剛寫好的HelloService
client.php

<?php
 require_once("SOAP/Client.php");
 $wsdl=new SOAP_WSDL('http://yourhost/server.php?wsdl');
 $helloClient = $wsdl->getProxy();
 echo $helloClient->Hello("This is a test!");
?>

輸出

Hello:[This is a test!]

是不是很簡單呢
此外這邊在補充一點
WSDL跟SOAP的關係
wsdl是用來描述你提供了哪些web service
用個簡單的說法就是
wsdl就是一個定義檔
定義你提供的物件
SOAP才是真正處理輸入以及輸出xml的主角


原文出處:酷!學園 - [心得]使用php提供Web service
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]soap 之 nusoap 的使用
soap 之 nusoap 的使用
今天不知道為什麼想起了soap 這個東西,然後就弄了下,在php上使用的是nusoap。 一些基本的使用,高深的麻煩您自己看手冊去
這個軟件的下載在 http://dietrich.ganx4.com/nusoap 下面我會加上附件。

說說這個東西,我曾經以為能用這個東西完成跨域名登陸,但是今天發現好像實現不了,
到底在什麼地方可以應用上,也很茫然,希望知道在那裡應用的朋友指點下,謝謝了!

關於soap的具體的原理,什麼的我就不多說,想知道的你網上自己找下,基本上就是http協議與xml的應用。
先說下個這個東西的實現原理,基本上就向服務器發送請求實現一個服務器上的函數運行,然後得到返回值。
值,我感覺應該是string或者數組,或者int值,應該不能用對象的。

先看一個基本的使用很簡單的
這是 soap_server.php 文件 這個在網絡上能找的到
include_once("lib/nusoap.php"); //插入文件
$server=new soap_server();     //生成對像
$server->configureWSDL("test_wsdl", "");
$server->wsdl->schemaTargetNamespace="urn:test_wsdl";
$server->register("hello", //方法名
array(
"name"=>"xsd:string",
"call"=>"xsd:string",
"tele"=>"xsd:string",
),//輸入參數
array(
"return"=>"xsd:string",
),//輸出參數
"urn:test_wsdl",//名字空間
"urn:test_wsdl#hello",//名字空間#要操作的函數名
"rpc",//style
"encoded",//use
"This is test."//說明
);
//test方法實現
function hello($name,$call,$tele) {
if($name==""){
return new soap_fault("Client","","Must supply a valid name.");
}
return "Hello, " . $name." ".$call." ".$tele;
}
//Use the request to (try to) invoke the service
$HTTP_RAW_POST_DATA=isset($HTTP_RAW_POST_DATA)?$HTTP_RAW_POST_DATA:"";
$server->service($HTTP_RAW_POST_DATA);

在你寫完了以後,在瀏覽器裡輸入url,應該會看到一個頁面,根據那個頁面分析下,會有很大的收穫,
client端要根據上面的使用
這個是soap _client.php
include_once("lib/nusoap.php");  //插入文件
//設置參數數組
$para=array(
"name"=>"sera1ph.Liu",
"call"=>"123456",
"phone"=>"12345678",
);
//生成客戶端對象,注意下面的url  ?wsdl是必須加的前面為服務端的文件
$client=new soapclient("http://localhost/nusoap/soap_server.php?WSDL");
//呼叫/使用 那個函數,注意名字空間的區分
$return=$client->call('hello',$para,"http://localhost/soap/test_wsdl","test_wsdl#hello");
print_r($return);


上面是一個很基本的使用,我想不過多的說了

下面看一個比較複雜的使用
require_once('../../lib/nusoap.php');
//取得值返回 返回的是一個數組
function validate($userName,$randomNum)
{
        $temp['userName'] = $userName;
        $temp['randomNum'] =$randomNum;
        return $temp;
}
//本想做個set一個get方法,但是這個時候發現了一個問題,以後再說
function refresh($refresh_userName,$refresh_randomNum)
{
        $temp['userName'] = $userName;
        $temp['randomNum'] =$randomNum;
        return $temp;
}

function logout($logout_userName)//註銷用戶名(退出登錄)
{
$flag=$logout_userName;

        if($logout_userName=="" || $logout_userName!="三石")
        {
        $flag = -1;
        }

return $flag;
}

$soap = new soap_server();
//參數一,服務名字,也就是server文件
//參數二,名字空間
$soap->configureWSDL('AuthorityServicewsdl', 'urn:AuthorityServicewsdl');
//參數設置空間
$soap->wsdl->schemaTargetNamespace = 'urn:AuthorityServicewsdl';
//上面跟原來的基本一樣,但是大家注意聲明的時候發生了變化
//下面是設置一個返回的數組類型
//參數一,為你自己命名的數據類型
//參數二,混合類型,不用管
//參數三。為結構體,或者數組(array)
//參數四,按照什麼排序,有三個選擇all(全部)|sequence(次序)|choice(選擇)
//參數五,基本約束
//注意:上面5個我們不用改變
//參數6,最重要的參數,也就是我們返回的類型想對應
//返回數組下標 =>array('name'=>"數組下標",'type'=>"xsd:對應的類型")
//類型基本包括 string,int, date,boolean 這幾種形式
$soap->wsdl->addComplexType('userInfo','complexType','struct','all','',
        array(
            'userName' => array('name'=>'userName', 'type'=>'xsd:string'),
           'randomNum' => array('name'=>'randomNum', 'type'=>'xsd:string')
                        )
                );

//這裡是註冊函數
//參數一,函數名
//參數二,是這個函數接受的參數,注意指定類型
//參數三,為返回的值,不一定名字非叫return,叫其他的也可以,注意返回的類型,
//我這裡是返回我自己定義的類型 tns:userInfo 如果為基本的類型為 xsd:string 這個樣子
//其他的參數,只要統一就可以了,尤其是名字空間跟 soapaction
$soap->register('validate', // method name
    array('userName' => 'xsd:string','randomNum' => 'xsd:string'), // input parameters
    //array('return' => 'xsd:string'), // output parameters
    array('return' => 'tns:userInfo'),
        'urn:AuthorityServicewsdl', // namespace
    'urn:AuthorityServicewsdl#validate', // soapaction
    'rpc', // style
    'encoded', // use
    '驗證用戶名及隨機數' // documentation
);

$soap->register('refresh', // method name
    array('refresh_userName' => 'xsd:string','refresh_randomNum' => 'xsd:string'), // input parameters
    //array('return' => 'xsd:string'),// output parameters
        array('return' => 'tns:userInfo'),
    'urn:AuthorityServicewsdl', // namespace
    'urn:AuthorityServicewsdl#refresh', // soapaction
    'rpc', // style
    'encoded', // use
    '按時地方' // documentation
);

$soap->register('logout', // method name
    array('logout_userName' => 'xsd:string'), // input parameters
    array('return' => 'xsd:int'), // output parameters
    'urn:AuthorityServicewsdl', // namespace
    'urn:AuthorityServicewsdl#logout', // soapaction
    'rpc', // style
    'encoded', // use
    '退出登錄' // documentation
);
//大家可能對 $HTTP_RAW_POST_DATA 這個變量比較疑惑,我們沒有定義,怎麼出來的呢
//我也有這樣的想法,不過我看了下手冊解釋是 usually is the value of $HTTP_RAW_POST_DATA
//所以大家就別管它了,就這樣使用吧
$soap->service($HTTP_RAW_POST_DATA);


我們現在看下 客戶端的使用
require_once('../../lib/nusoap.php');

$client=new soapclient('http://localhost/nusoap/samples/server/AuthorityService.php?wsdl',true);
$err = $client->getError();

$username = "三石";
$randomnum = "d8A9";
$params1 = array('userName'=>$username,'randomNum'=>$randomnum);
$reversed = $client->call('validate',$params1);//此為返回值
//echo "註冊值<br>";
print_r ($reversed);
echo "<br>";

$refresh_username = "三石";
$refresh_randomnum = "d8A9";
$params1 = array('refresh_userName'=>$refresh_username,'refresh_randomNum'=>$refresh_randomnum);
$reversed = $client->call('refresh',$params1);
//echo "取得值<br>";
print_r ($reversed);
echo "<br>";

$logout_username = "三石";
$params1 = array('logout_userName'=>$logout_username);
$reversed = $client->call('logout',$params1);
echo $reversed;

這個就不用多說了,一看應該就明白了 是數組返回的我使用print_r輸出了
關於這個功能,我說下我做的實驗
首先我用set方法設置了下一個公共變量的值,當用get取得的時候,值為空
說明,每次是建立一個新的訪問所以值沒有保留
測試2,我使用cookie 設置的值,在get方法的時候,沒有取得
說明:沒鬧明白原因
測試3,使用session 在get方法的時候,也沒有取得值
說明,沒鬧明白
但是取得文件或者數據庫連接取得值是沒有問題的,也就是可以取得固定介質中的值,文件或者數據庫

這個東西到底能幹什麼還真不清楚,我想是可以完成,2種不同語言的交接,比如 php與asp與jsp的交互
也許有人茫然了,我這裡丟了一個感念,soap返回的是一個流,所有可以當作文本流來對待,
使用socket取得。
關於nusoap的使用就到這裡了,我不大去弄它的具體原理了,能夠使用就夠了!所以沒有對nusoap的代碼做分析

作者:叁石
mail:sanshi0815@tom.com



原文出處:soap 之 nusoap 的使用 - 喜悦原创 - 喜悦国际村
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]使用nusoap建立web service-範例




首先 分別撰寫cliet與server端程式,放在nusoap資料夾下



server端部分程式碼撰寫原則:



  1. 撰寫欲被client調用的函式connectandsave($content)

  2. 引入nusoap require_once("lib/nusoap.php");

  3. 建立soap_server實體 new soap_server()

  4. 配置WSDL文件敘述 configureWSDL

  5. 為服務註冊register方法函式(connectandsave)

  6. 使用service方法執行方法並回傳值 $server->service($POST_DATA);



server端-WSservertest.php:



<?php

//定義service處理函式

function connectandsave($content)

{

$xx = main::toStore($content);



return "get \r\n" . main::$accuracy2 . "\r\n" ;

//return "get \r\n" . $content . "\r\n" ."dd";



}

date_default_timezone_set("Asia/Taipei");

require_once("lib/nusoap.php");





$server = new soap_server();// 初始化一個service物件實體

$server->soap_defencoding='UTF-8';

$server->decode_utf8=false;

$server->configureWSDL("SimpleService");// 配置 WSDL 描述,叫用時以此為類別名稱

$server->wsdl->schemaTargetNamespace = $namespace; // set namespace

// register service's WebMethod,註冊過的程序才能被訪問到

// $server->register('answerHello',array('name' => 'xsd:string'),array('return' => 'xsd:string'));

$server->register(

// method name:

'connectandsave',

// parameter list:

array('name'=>'xsd:string'),

// return value(s):

array('return'=>'xsd:string'),

// namespace:

$namespace,

// soapaction: (use default)

false/*,

// style: rpc or document

'document',

// use: encoded or literal

'encoded',

// description: documentation for the method

'Anser Hello to World '*/);





//把client端 post 過來的資料,傳給server物件的 service 方法處理。

//service 方法處理的資料會借調用相應的函式回傳給叫用端

$POST_DATA = isset($GLOBALS['HTTP_RAW_POST_DATA'])

? $GLOBALS['HTTP_RAW_POST_DATA'] : '';



$server->service($POST_DATA);

exit();

?>



其中main是自定類別,裡面就是自己寫的一些程序



接下來示範如何調用剛剛寫好的函式connectandsave

client端部分程式碼撰寫原則:



  1. 引入nusoap require_once("lib/nusoap.php");

  2. 建立soapclient()實體 new soapclient()

  3. 將要傳送的資料陣列化(array)

  4. 使用call方法叫用欲呼叫的方法call(函式名)

  5. 印出call完後的值;





client端-WSclienttest.php :



<?php

require_once("lib/nusoap.php");

//初始化 client 物件,是class soapclient 的一個實體

//把服務程序的 URL 地址傳遞给soapclient類別的構造函式

$client = new soapclient('http://xxxx/nusoap/WSservertest.php'); //後面利用client物件的 call 方法調用 WEB 服务的程序'GPSconnectandsave'



$myname = 'clark' ;

// $Content = '25.07433874,121.52545941,2009-05-23,17:53:56,1.2,5,2.3,2.6,8.3,xxx' ; //中原國小門口

$Content = '24.956846,121.242451,2009-05-23,17:53:56,1.2,5,2.3,2.6,8.3,xxx' ; //中原大草皮



$parameters=array('24.956846,121.242451,2000-01-01,17:53:56,1.2,5,2.3,2.6,8.3,xxx');

$str=$client->call('connectandsave',$parameters); //call('函式名',匹配的參數) 函式名為在WSservertest.php中所註冊的函式



//$str=$client->call('hello'); //客户端对象的 getError() 方法可以用来检查调用过程是否出现错误。

//如果没有错误, getError() 方法返回 false ;如果有错误, getError()方法返回错误信息。

if (!$err=$client->getError()) {

echo " return:",htmlentities($str,ENT_QUOTES);
//the optional second quote_style parameter lets you define what will be done with
'single' and "double" quotes. It takes on one of three constants with the default
being ENT_COMPAT: ,ENT_QUOTES Will convert both double and single quotes.

} else {

echo " error :",htmlentities($err,ENT_QUOTES);

}



//觀察request 和 response響應

echo '<p/>';

echo 'Request:';

echo '<pre>',htmlspecialchars($client->request,ENT_QUOTES),'</pre>';

echo 'Response:';

echo '<pre>',htmlspecialchars($client->response,ENT_QUOTES ),'</pre>';



?>








原文出處:
研究生了沒: 使用nusoap建立web service-範例
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]php soap实例讲解
PHP技巧:php soap實例講解
發佈日期:2010-10-12 09:55 來源:中國建站

我要投稿SOAP是基於XML和HTTP通信協議,xml各種平台,各種語言都支持的一個種語言。http呢它得到了所有的因特網瀏覽器及服務器的支持。

一,什麼是soap,什麼是wsdl,為什麼要用他們

SOAP是基於XML和HTTP通信協議,xml各種平台,各種語言都支持的一個種語言。http呢它得到了所有的因特網瀏覽器及服務器的支持。

WSDL 指網絡服務描述語言 (Web Services Description Language),是一種使用 XML 編寫的文檔。這種文檔可描述某個 Web service。它可規定服務的位置,以及此服務提供的操作。

我是做php的,你是java的,他是做.net,如果我們三個之間要進行通信,要進行數據交換,怎麼辦呢?我們需要一個能和我們都能通信的工具。soap,wsdl被創造出來,使得運行在不同的操作系統並使用不同的技術和編程語言的應用程序可以互相進行通信。

二,實例

如果php要使用soap的話,通常做法是,添加了一下php的soap模塊,在php.ini裡面加上soap.so,下面介紹一個不要添加soap.so文件,也可以實現soap的方法

nusoap是php寫的一個功能文件,包涵進來就可以用了,網上很多自己去搜一下吧。

1,不使用wsdl

a,服務端helloworld2.php

//包涵nusoap.php
require_once('./lib/nusoap.php');
//創建服務端
$server = new soap_server;
//定義客戶端調用方法
$server->register('hello');
//調用方法以及參數
function hello($name) {
return 'Hello, ' . $name;
}
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
?>


b,客戶端hello.php

//包涵nusoap.php
require_once('./lib/nusoap.php');
//新建一個soap客戶端,調用服務端提供的wsdl
//$client = new soapclient('http://localhost/test/hellowsdl2.php?wsdl', true);
$client = new soapclient('http://localhost/test/helloworld2.php');
//查看一下是不是報錯
$err = $client->getError();
if ($err) {
//顯示錯誤
echo '
Constructor error
' . $err . '
';
}
//調用服務端的方法
$result = $client->call('hello', array('person' => "this is a test"));
echo '
Result
';
print_r($result);
echo '
';
?>


2,使用wsld

a,服務器端

//包涵nusoap.php
require_once('./lib/nusoap.php');
//新建一個soap服務
$server = new soap_server();
//初始化支持wsdl
$server->configureWSDL('hellowsdl2', 'urn:hellowsdl2');
//定義數據結構來接收數據
$server->wsdl->addComplexType(
'Person',
'complexType',
'struct',
'all',
'',
array(
'firstname' => array('name' => 'firstname', 'type' => 'xsd:string'),//後面的type定義數據的類型,這個是string
'age' => array('name' => 'age', 'type' => 'xsd:int'),//後面的type定義數據的類型,這個是int
'gender' => array('name' => 'gender', 'type' => 'xsd:string')//後面的type定義數據的類型,這個是string
)
);
$server->wsdl->addComplexType(
'SweepstakesGreeting',
'complexType',
'struct',
'all',
'',
array(
'greeting' => array('name' => 'greeting', 'type' => 'xsd:string'),
'winner' => array('name' => 'winner', 'type' => 'xsd:string')
)
);
//服務器定義的soap調用方法
$server->register('hello', // 方法名字hello,方法就在下面
array('person' => 'tns:Person'), // 客戶端傳來的變量
array('return' => 'tns:SweepstakesGreeting'), //返回參數
'urn:hellowsdl2', // soap名
'urn:hellowsdl2#hello', // soap的方法名
'rpc', // 使用的方式
'encoded', // 編碼
'test' // 存檔
);
//定義上面註冊過的函數hello
function hello($person) {
$greeting = 'Hello, ' . $person['firstname'] .
'. It is nice to meet a ' . $person['age'] .
' year old ' . $person['gender'] . '.';
$winner = 'Scott';
//要返回的數據
return array(
'greeting' => $greeting,
'winner' => $winner
);
}
// 請求時(試圖)調用服務
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
?>


b,客戶端

//包涵nusoap.php
require_once('./lib/nusoap.php');
//新建一個soap客戶端,調用服務端提供的wsdl
//$client = new soapclient('http://localhost/test/hellowsdl2.php?wsdl', true);
$client = new soapclient('http://localhost/test/helloworld2.php');
//查看一下是不是報錯
$err = $client->getError();
if ($err) {
//顯示錯誤
echo '
Constructor error
' . $err . '
';
}
//要向服務端要傳的參數
$person = array('firstname' => 'Willi', 'age' => 22, 'gender' => 'male');
//調用服務端的方法
$result = $client->call('hello', array('person' => $person));
//錯誤審核
if ($client->fault) {
echo '
Fault
';
print_r($result);
echo '
';
} else {
$err = $client->getError();
if ($err) {
echo '
Error
' . $err . '
';
} else {
echo '
Result
';
print_r($result);
echo '
';
}
}
//顯示請求信息
echo '
Request
';
echo '
' . htmlspecialchars($client->request, ENT_QUOTES) . '
';
//顯示返回信息
echo '
Response
';
echo '
' . htmlspecialchars($client->response, ENT_QUOTES) . '
';
//顯示調試信息
echo '
Debug
';
echo '
' . htmlspecialchars($client->debug_str, ENT_QUOTES) . '
';
?>


上面二個例子不管是客戶端,還是服務器端,都是用php寫的,你可以試著用多種語言來寫,來測試一下。不管你是用php的模塊,還是用nusoap,裡面具體方法就不在這多說了,手冊裡面都有。

SOAP在這裡就不用介紹了, 這裡只是簡單的實現一個SOAP的實例, 不多說 ,看代碼吧。 soap分為server和client, 我們要使client去調用server的代碼. 首先看server短的代碼:

這個是server端的代碼: server.php
//聲明一個函數add() ,並返回它的值
function add($a,$b){
return $a+$b;
}
//實例化一個SoapServer對像, 並將add函數註冊成為其方法
$server = new SoapServer(null,array('uri'=>'http://localhost/')); //指定server端代碼的URI(資源標誌符)
$server->addFunction("add");
$server->handle();
?>

然後使用client端的代碼來調用server端的代碼: client的代碼也很簡單: 如下:

這個是client端的代碼 client.php
//建立一個參數數組,存儲要訪問的提供soap服務的計算機的地址與程序
$arrOptions=array(
'uri'=>'http://localhost/',
'location'=>'http://localhost/soap/server.php', //注意: 這個location指定的是server端代碼在服務器中的具體位置, 我的是在本地根目錄下的soap目錄中,
'trace'=>true,
);
$soapObject = new SoapClient(null,$arrOptions); //實例化客戶端對像
echo $soapObject->add(20,30); //調用服務器端的函數add並返回值50
?>

ok, 結束了 !

原文出處:PHP技巧:php soap实例讲解 - 新风IT教育网
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]NuSOAP的使用说明
NuSOAP的使用說明Submitted by jiashixiang on 2006, July 24, 8:36 PM. php學習

NuSOAP 是 PHP 環境下的 WEB 服務編程工具,用於創建或調用 WEB 服務。它是一個開源軟件,當前版本是 0.7.2 ,支持 SOAP1.1 、 WSDL1.1 ,可以與其他支持 SOAP1.1 和 WSDL1.1 的系統互操作。 NuSOAP 完全由PHP語言編寫,由一系列 PHP 類組成,不需要擴展庫的支持,這種特性使得 NuSOAP 可以用於所有的 PHP 環境,不受服務器安全設置的影響。

1. NuSOAP 的獲取和安裝
NuSOAP 項目建立在 SourceForge 上,網絡地址是: http://sourceforge.net/projects/nusoap/ ,這裡,可以下載到 NuSOAP 的最新的版本。
NuSOAP 的安裝比較簡單,把下載的 NuSOAP 的文件拷貝到服務器上,可以放在獨立的目錄裡,也可以與程序代碼放在相同的目錄裡,只要你的 PHP 代碼能夠訪問到這些文件就可以了。
本文的測試環境基於 PHP4.3.2 和 NuSOAP 0.7.2 版本, NuSOAP 安裝在 WEB 目錄「 /nusoap 」裡,有兩個子目錄, lib 和 samples 。其中, lib 目錄下存放 NuSOAP 的所有源代碼文件, samples 目錄下是NuSOAP開發小組提供一些的例子。測試文件存放在 WEB 目錄「 /nusoap 」裡。

2. NuSOAP 的使用
NuSOAP 由一 PHP 的類組成,其中最常用到的是類soap_server和類soalclient。類soap_server 用於創建 WEB 服務,類soapclient在訪問WEB服務時會用到。
2.1 一個簡單的例子: Hello World
這個例子將利用 NuSOAP 創建一個簡單的 WEB 服務,並利用 NuSOAP 創建一個客戶端程序,調用這個服務。這個服務唯一的功能就是向客戶端返回一個字符串「 Hello World 」。首先,創建 WEB 服務程序代碼文件「 /nusoap/nusoap_server1.php 」:
//把 NuSOAP 的源文件包含到當前的代碼文件裡
<?php
require_once("lib/nusoap.php");
//定義服務程序
function hello() {
  return 'Hello World!';
}
//初始化服務對像 , 這個對象是類 soap_server 的一個實例
$soap = new soap_server; //調用服務對象的 register 方法註冊需要被客戶端訪問的程序。
//只有註冊過的程序,才能被遠程客戶端訪問到。
$soap->register('hello'); //最後一步,把客戶端通過 post 方式提交的數據,傳遞給服務對象的 service 方法。
//service 方法處理輸入的數據,調用相應的函數或方法,並且生成正確的反饋,傳回給客戶端。
$soap->service($HTTP_RAW_POST_DATA);
?>

至此, WEB 服務程序代碼文件已經建好,接下來,創建一個客戶端程序代碼文件「 /nusoap/nusoap_client1.php 」,調用 WEB 服務:
//把 NuSOAP 的源文件包含到當前的代碼文件裡
<?php
require_once("lib/nusoap.php");
//初始化客戶端對象,這個對象是類 soapclient 的一個實例,
//把服務程序的 URL 地址傳遞給soapclient類的構造函數。
$client = new soapclient('http://127.0.0.1/nusoap/nusoap_server1.php'); //利用客戶端對象的 call 方法調用 WEB 服務的程序
$str=$client->call('hello'); //客戶端對象的 getError() 方法可以用來檢查調用過程是否出現錯誤。
//如果沒有錯誤, getError() 方法返回 false ;如果有錯誤, getError()方法返回錯誤信息。
if (!$err=$client->getError()) {
    echo " 程序返回 :",htmlentities($str,ENT_QUOTES);
} else {
    echo " 錯誤 :",htmlentities($err,ENT_QUOTES);
}
?>

至此,客戶端程序也建立好了,打開瀏覽器,訪問客戶端程序,看一下結果。這個例子,瀏覽器會顯示字符串:「程序返回 :Hello World! 」
2.2 傳遞參數和返回錯誤信息的方法
再通過例子說明傳遞參數和返回錯誤信息的方法。這個例子實現兩個字符串的連接,參數是兩個字符串,返回值是由兩個參數連接而成的字符串。首先,創建服務程序代碼文件「 /nusoap/nusoap_server2.php 」,完整的代碼如下:
<?php
require_once("lib/nusoap.php");
function concatenate($str1,$str2) {
    if (is_string($str1) && is_string($str2))
        return $str1 . $str2;
    else
        return new soap_fault(' 客戶端 ','','concatenate 函數的參數應該是兩個字符串 ');
}
$soap = new soap_server;
$soap->register('concatenate');
$soap->service($HTTP_RAW_POST_DATA);
?>

與 2.1 節 WEB 服務程序的代碼比較,這裡的代碼結構大體是相同的。注意以下兩點:
服務程序的定義不同,帶有兩個參數。 NuSOAP 註冊服務程序的過程還是一樣的,都是調用服務對象的 register 方法。
這裡使用了 NuSOAP 的一個新類 soap_fault 。當傳入的兩個參數有一個不是字符串時,程序通過這個類把錯誤信息返回給客戶端。這個類的構造函數有 4 個參數:
soap_fault([fault],[faultactor],[faultstring],[faultdetail]);
fault
必填參數 , 建議值為「 Client 」或「 Server 」,指明錯誤是客戶端的錯誤還是服務端的錯誤。
faultactor
預留項,現在還沒有使用
faultstring
錯誤的描述信息
faultdetail
可選項, XML 格式的數據 , 說明詳細的錯誤信息
ex:soap_fault('客戶端 ','','concatenate 函數的參數應該是兩個字符串 ');

客戶端程序代碼文件「 /nusoap/nusoap_client2.php 」的完整內容如下 :
<?php
require_once("lib/nusoap.php");
$client = new soapclient('http://127.0.0.1/nusoap/nusoap_server2.php');
$parameters=array(' 字符串 1',' 字符串 2');
$str=$client->call('concatenate',$parameters);
if (!$err=$client->getError()) {
    echo " 程序返回 :",$str;
} else {
    echo " 錯誤 :",$err;
}
?>

NuSOAP 的客戶端調用帶參數的 WEB 服務時,使用數組傳遞參數。 $parameters 是一個數組,其中依次是每個參數的值。客戶端在調用遠程的服務程序時,使用帶有兩個參數的 call 方法,第一個參數是服務程序的名稱,第二個參數是服務程序的參數數組,這裡是 $parameters 。通過瀏覽器訪問上面的客戶端程序,瀏覽器上會顯示字符串:「 程序返回 : 字符串 1 字符串 2 」
接下來,試著給 WEB 服務程序傳入錯誤參數,修改上面的客戶端程序,把生成參數數組的語句改成: $parameters=array(「 字符串 」,12) ,再通過瀏覽器訪問客戶端程序,瀏覽器上會顯示字符串:「錯誤 : 客戶端 : concatenate 函數的參數應該是兩個字符串」。 WEB 服務程序判斷傳入的參數有一個不是字符串,通過 soap_fault 給客戶端返回錯誤信息。
2.3 調試的方法
NuSOAP中常用的調試方法有三種:
2.3.1 soapclient 類的 request 和 response 成員變量
最直接的調試方法就是檢查訪問 WEB 服務的過程中,客戶端發出的 request 信息和服務端返回的 response 信息。 soapclient 類的 request 和 response 成員變量包含這些信息,在程序中顯示出這兩個變量的內容,可以幫助分析程序運行的情況。看下面的代碼:
<?php
require_once("lib/nusoap.php");
$client = new soapclient('http://127.0.0.1/nusoap/nusoap_server2.php');
$parameters=array(' 字符串 1',' 字符串 2');
$str=$client->call('concatenate',$parameters);
if (!$err=$client->getError()) {
    echo " 程序返回 :",$str;
} else {
    echo " 錯誤 :",$err;
}
//下面顯示request和response 變量的內容
echo '<p/>';
echo 'Request:';
echo '<pre>',htmlspecialchars($client->request,ENT_QUOTES),'</pre>';
echo 'Response:';
echo '<pre>',htmlspecialchars($client->response,ENT_QUOTES ),'</pre>';
?>

2.3.2 soapclient 類的 debug_str 成員變量
soapclient 類的 debug_str 成員變量提供了更為詳細的調試信息,查看這個變量的內容,可以更好地幫助程序調試。
2.3.3 WEB 服務程序提供的調試方法
WEB 服務程序代碼中,在創建 soap_server 類的實例前,定義變量 $debug=1 。調試信息作為備註,放在 SOAP 消息的尾部返回客戶端,客戶端通過查看 WEB 服務的 response 信息來查看調試信息。
<?php
require_once("lib/nusoap.php");
function concatenate($str1,$str2) {
    if (is_string($str1) && is_string($str2))
        return $str1 . $str2;
    else
        return new soap_fault(' 客戶端 ','','concatenate 函數的參數應該是兩個字符串 ');
}
$debug=1; //定義調試
$soap = new soap_server;
$soap->register('concatenate');
$soap->service($HTTP_RAW_POST_DATA);
?>

2.4 對 WSDL 的支持
NuSOAP 內部通過類 "WSDL" 實現對 WSDL 的支持。對於 NuSOAP 的用戶來說,不需要關心內部的WSDL類是如何工作的,正確地使用 soap_server 類和 soapclient 類就可以實現對 WSDL 的支持。
2.4.1 創建支持 WSDL 的 WEB 服務
為了實現 WEB 服務程序對 WSDL 的支持,需要使用 soap_server 的 configureWSDL 方法,並且在調用 soap_server 的 register 方法註冊 WEB 服務程序時,需要提供更詳細的參數。看下面的代碼,代碼的文件名是 「/nusoap/nusoap_server3.php」。
<?php
require_once("lib/nusoap.php");
function concatenate($str1,$str2) {
    if (is_string($str1) && is_string($str2))
        return $str1 . $str2;
    else
        return new soap_fault(' 客戶端 ','','concatenate 函數的參數應該是兩個字符串 ');
}
$soap = new soap_server;
$soap->configureWSDL('concatenate'); // 初始化對 WSDL 的支持
// 註冊服務
$soap->register('concatenate',
array("str1"=>"xsd:string","str2"=>"xsd:string"), // 輸入參數的定義
array("return"=>"xsd:string") // 返回參數的定義
);
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$soap->service($HTTP_RAW_POST_DATA);
?>

現在打開瀏覽器,訪問剛才建立的文件,http://127.0.0.1/nusoap/nusoap_server3.php,結果如下:
concatenate
View the WSDL for the service. Click on an operation name to view it's details.
concatenate

點擊函數名稱concatenate,可以看到對函數的描述。點擊"WSDL",或者訪問WEB服務文件,並在後面加上查詢字符串"?wsdl"(http://127.0.0.1/nusoap/nusoap_server3.php?wsdl),可以得到WEB服務的WSDL內容。
2.4.2 通過 WSDL 調用 WEB 服務
通過 WSDL 調用 WEB 服務,與不通過 WSDL 調用 WEB 服務,程序的結構大體相同。區別在於,通過 WSDL 調用 WEB 服務,初始化 soapclient 類時,傳入兩個參數到 soapclient 的構造函數,第一個參數是 WSDL 文件的地址,第二個參數指定是否使用 WSDL ,指定為 true 即可。看下面的代碼,代碼的文件名是 「 /nusoap/nusoap_client3.php 」
<?php
require_once("lib/nusoap.php");
$client = new soapclient('http://127.0.0.1/nusoap/nusoap_server3.php?wsdl',true);
$parameters=array(' 字符串 1',' 字符串 2');
$str=$client->call('concatenate',$parameters);
if (!$err=$client->getError()) {
    echo " 程序返回 :",$str;
} else {
    echo " 錯誤 :",$err;
}
?>

2.4.3 代理的使用
NuSOAP 提供代理的方法調用遠程 WEB 服務。這種方法,在客戶端程序裡面創建一個遠程服務的代理對象,通過代理直接調用遠程的 WEB 服務,而不需要通過 soalclient 類的 call 方法。看下面的代碼。
<?php
require_once("lib/nusoap.php");
$client = new soapclient('http://127.0.0.1/nusoap/nusoap_server3.php?wsdl',true);
$proxy=$client -> getProxy(); // 創建代理對像 (soap_proxy 類 )
$str=$proxy->concatenate(" 參數 1"," 參數 2"); // 直接調用 WEB 服務
if (!$err=$proxy->getError()) {
    echo " 程序返回 :",$str;
} else {
    echo " 錯誤 :",$err;
}
?>


3. 更多的學習資源
http://dietrich.ganx4.com/nusoap/
•Scott Nichol. Programming with NuSOAP. 24 Apr 2003:http://www.scottnichol.com/nusoapprog.htm
•Scott Nichol. Programming with NuSOAP Part 2. 29 May 2003:http://www.scottnichol.com/nusoapprog2.htm
•Scott Nichol. Introduction to NuSOAP. 03 Nov 2004:http://www.scottnichol.com/nusoapintro.htm
•Scott Nichol. Programming with NuSOAP Using WSDL. 11 Nov 2003:http://www.scottnichol.com/nusoapprogwsdl.htm

原文出處: NuSOAP的使用说明 - php学习,nusoap,jiashixiang,上火网|上火|shanghuo.net|onfire - Powered by shanghuo
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]NuSOAP教程 - PHP教程
NuSOAP教程

這個文檔描述了如何取得和安裝 NuSOAP,然後提供一些實例來說明 NuSOAP 的功能,這並不是一個全面的 NuSOAP 的介紹,但是希望能夠然一些 PHP 開發者可以有一個很好的入門。

NuSOAP 是一組 PHP 類,它讓開發者可以創建和使用 SOAP web services。它不需要安裝任何的 PHP 擴展。它是在2004年12月3日被開發,當前的版本是 NuSOAP(0.6.7) 。支持 SOAP 1.1 規範,它能夠生產 WSDL 1.1 ,當然也可以使用它,同時也支持 rpc/encoded and document/literal service。但是,必須注意 NuSOAP 沒有像 .NET 和 Apache Axis 那樣提供完全的實現。

Hello, World
我會以 "Hello, World" 為實例做開始,編寫基本的 NuSOAP 客戶端和服務器端的代碼。

我們先從服務器端開始,應為沒有服務器端,有客戶端也是沒有意義的。我們將編寫一個帶有單個參數並返回一個字符串,名叫 Hello 的 SOAP 方法,希望代碼中的註釋能夠提供有效的說明。
<?php
// Pull in the NuSOAP code
require_once('nusoap.php');
// Create the server instance
$server = new soap_server;
// Register the method to expose
$server->register('hello');
// Define the method as a PHP function
function hello($name) {
    return 'Hello, ' . $name;
}
// Use the request to (try to) invoke the service
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
?>


以下是客戶端的代碼,有一些重要的事情需要注意:首先,當創建實例 soapclient 時,需要指定一個 service 的 URL 為參數,在這個實例中,helloworld.php 從 http://localhost/phphack 訪問的。當然,你要使用的 services 放在不同的 URL;第二,當調用service 時,第一個參數是 service 的名字,必須要匹配有效的方法名(有的服務器是大小寫敏感的)。在這個實例,他必須匹配在 helloworld.php 中已經註冊了的方法。最後,第二個參數是一個數組,它將是傳遞給 SOAP service 方法作為參數。既然 helloworld.php 中的方法 hello 只有一個參數,那麼數組就只有一個元素。
<?php
// Pull in the NuSOAP code
require_once('nusoap.php');
// Create the client instance
$client = new soapclient('http://localhost/phphack/helloworld.php');
// Call the SOAP method
$result = $client->call('hello', array('name' => 'Scott'));
// Display the result
print_r($result);
?>


Debugging
編程時,當有問題出現的時候你都需要調試。NuSOAP 提供了一組工具來幫助你做這個工作。NuSOAP 調試的時候需要查看的信息是發送的請求信息和返回的相應信息。NuSOAP 的客戶端類允許你通過它的兩個成員來查看這些信息。例如,這裡是顯示請求和響應的 helloworldclient.php 的修改版。在下一部分我會回顧顯示在客戶端代碼的請求和響應信息。
<?php
// Pull in the NuSOAP code
require_once('nusoap.php');
// Create the client instance
$client = new soapclient('http://localhost/phphack/helloworld.php');
// Call the SOAP method
$result = $client->call('hello', array('name' => 'Scott'));
// Display the result
print_r($result);
// Display the request and response
echo '<h2>Request</h2>';
echo '<pre>' . htmlspecialchars($client->request, ENT_QUOTES) . '</pre>';
echo '<h2>Response</h2>';
echo '<pre>' . htmlspecialchars($client->response, ENT_QUOTES) . '</pre>';
?>


NuSOAP 也提供了一個方法使用它的類就可以通過日誌來查看調試信息。加入以下的代碼將會顯示冗長的調試信息。不幸的是輸出的說明必須留給讀者。
// Display the debug messages
echo '<h2>Debug</h2>';
echo '<pre>' . htmlspecialchars($client->debug_str, ENT_QUOTES) . '</pre>';


服務器端能夠提供相似的調試信息,有趣的是,這些調試信息是在SOAP 的相應的末尾以 xml 格式顯示,因此它可以在客戶端中查看到。服務器端的調試看起來像這樣:
<?php
// Pull in the NuSOAP code
require_once('nusoap.php');
// Enable debugging *before* creating server instance
$debug = 1;
// Create the server instance
$server = new soap_server;
// Register the method to expose
$server->register('hello');
// Define the method as a PHP function
function hello($name) {
    return 'Hello, ' . $name;
}
// Use the request to (try to) invoke the service
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
?>


調試的第三個方法不算是真正的調試,它是很好的編程實踐。上面的實例在調用 SOAP 的時候沒有做錯誤的檢查,更健壯的客戶端會像這樣:
<?php
// Pull in the NuSOAP code
require_once('nusoap.php');
// Create the client instance
$client = new soapclient('http://localhost/phphack/helloworld.php');
// Check for an error
$err = $client->getError();
if ($err) {
    // Display the error
    echo '<p><b>Constructor error: ' . $err . '</b></p>';
    // At this point, you know the call that follows will fail
}
// Call the SOAP method
$result = $client->call('hello', array('name' => 'Scott'));
// Check for a fault
if ($client->fault) {
    echo '<p><b>Fault: ';
    print_r($result);
    echo '</b></p>';
} else {
    // Check for errors
    $err = $client->getError();
    if ($err) {
        // Display the error
        echo '<p><b>Error: ' . $err . '</b></p>';
    } else {
        // Display the result
        print_r($result);
    }
}
?>


為了測試代碼,需要引起錯誤發生,例如,改變調用的方法名稱 hello 為 goodbye。

Request and Response
我在上面的例子中已經展示了顯示 SOAP 的請求和響應信息是如此的容易,在這裡 hello2client.php 的請求信息:
POST /phphack/helloworld2.php HTTP/1.0
Host: localhost
User-Agent: NuSOAP/0.6.8 (1.81)
Content-Type: text/xml; charset=ISO-8859-1
SOAPAction: ""
Content-Length: 538

<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:si="http://soapinterop.org/xsd">
<SOAP-ENV:Body>
  <ns1:hello xmlns:ns1="http://testuri.org">
   <name xsi:type="xsd:string">Scott</name>
  </ns1:hello>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

在 HTTP headers 裡,你會看到 SOAPAction 是一個空的字符串,這是它的默認值。你的 service 方法可以設置 SOAPAction 的值,你的客戶端代碼可以指定 SOAPAction 作為參數來調用方法。

在 XML payload,你可以看到 NuSOAP 使用和Latin-1一樣著名的 ISO-8859-1 做為編碼,為了指定不同的編碼,你可以在客戶端 soapclient 的實例設置 soap_defencoding 屬性。使用指定的編碼來編碼參數的數據當然就是程序員的責任。幸運地,在 SOAP 裡PHP提供了很多函數來編碼和解碼最通用的編碼數據,如 UTF-8。


另一件事情要注意的是,元素指定要調用的方法,名稱為 hello 的元素被放在 http://tempuri.org的域名下,指定真實的域名是最佳的實踐,對於很多 services 也是很有必要的。這裡展示了一個未來的文檔:

SOAP 服務的響應像以下:
HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Wed, 03 Nov 2004 21:32:34 GMT
X-Powered-By: ASP.NET
X-Powered-By: PHP/4.3.4
Server: NuSOAP Server v0.6.8
X-SOAP-Server: NuSOAP/0.6.8 (1.81)
Content-Type: text/xml; charset=ISO-8859-1
Content-Length: 556

<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:si="http://soapinterop.org/xsd">
<SOAP-ENV:Body>
  <ns1:helloResponse xmlns:ns1="http://tempuri.org">
   <return xsi:type="xsd:string">Hello, Scott</return>
  </helloResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>


本篇文章来源于 PHP资讯 原文链接:http://www.phpq.net/tutorial/nusoap.html
前一個主題 | 下一個主題 | 頁首 | | |



Powered by XOOPS 2.0 © 2001-2008 The XOOPS Project|