Web service 是一個軟體系統,設計來支援電腦之間跨網路相互存取。在Web應用程序,它通常用一套API,可以被互聯網存取和執行在遠端系統主機上的被請求服務。系統主機所要求的服務。例如,以Flex為基礎的用戶端可能會引用函數實作在伺服器端執行PHP的Web應用程式。 Web service依賴SOAP作為通訊協定堆疊的基礎層。
Yii提供CWebService和CWebServiceAction簡化了在Web應用程式實作Web service。這些API以類別形式實現,稱為service providers. Yii將為每個類別產生一個WSDL,描述什麼API有效和客戶端怎麼引用。當客戶端引用API,Yii將實例化對應的service provider和呼叫被請求的API來完成請求。
註: CWebService 依賴PHP SOAP extension 。請確定您是否在試用本節中的範例前允許此擴充。
正如我們上文所述,service provider是一個類別定義能被遠端引用的方法。 Yii依靠doc comment and class reflection識別 哪些方法可以被遠端呼叫和他們的參數還有回傳值。
讓我們以一個簡單的股票報價服務開始。這項服務允許客戶端請求指定股票的報價。我們確定service provider如下。請注意,我們定義擴充CController的提供類別StockController
。這是不是必需的。馬上我們將解釋為什麼這樣做。
class StockController extends CController { /** * @param string the symbol of the stock * @return float the stock price * @soap */ public function getPrice($symbol) { $prices=array('IBM'=>100, 'GOOGLE'=>350); return isset($prices[$symbol])?$prices[$symbol]:0; //...return stock price for $symbol } }
在上面的,我們透過在文件註解中的@soap
標籤聲明getPrice
方法為一個Web service API。依靠文檔註解指定輸入的參數資料類型和傳回值。其他的API可使用類似方式聲明。
已經定義了service provider,我們使他能夠透過客戶端存取。特別是,我們要建立一個控制器動作暴露這個服務。可以做到這一點很容易,在控制器類別中定義一個CWebServiceAction動作。在我們的例子中,我們把它放在StockController
中。
class StockController extends CController { public function actions() { return array( 'quote'=>array( 'class'=>'CWebServiceAction', ), ); } /** * @param string the symbol of the stock * @return float the stock price * @soap */ public function getPrice($symbol) { //...return stock price for $symbol } }
這就是我們需要建立的Web service!如果我們嘗試存取 動作網址http://www.php.cn/
,我們將 看到很多XML內容,這實際上是我們定義的Web service的WSDL描述。
提示:在預設情況下, CWebServiceAction 假設目前的控制器 是service provider。這就是因為我們定義
getPrice
方法在StockController
中。
要完成這個例子,讓我們建立一個客戶端來消費我們剛剛建立的Web service。範例中的客戶端用php寫的,但可以用別的語言寫,例如Java
, C#
, Flex
等等。
$client=new SoapClient('http://hostname/path/to/index.php?r=stock/quote'); echo $client->getPrice('GOOGLE');
在網頁中或控制台模式中運行以上腳本,我們將看到GOOGLE
的價格350
。
當定義的方法和屬性被遠端訪問,我們需要指定輸入和輸出參數的資料類型。以下的原始資料型別可以使用:
str/string: 對應 xsd:string
;
int/integer: 對應🜎5:int float
;
bool/boolean: 對應 xsd:boolean
;
date: 對應
;
;
我們也可以使用數組類型透過附加
[]
getPosts網頁API,回傳一個
Post
class PostController extends CController { /** * @return Post[] a list of posts * @soap */ public function getPosts() { return Post::model()->findAll(); } } class Post extends CActiveRecord { /** * @var integer post ID * @soap */ public $id; /** * @var string post title * @soap */ public $title; }
5. Class Mapping(類別映射)為了從客戶端得到複合型參數,應用程式需要定義從WSDL類型到對應PHP類的映射。這是透過設定CWebServiceAction的屬性classMap。
class PostController extends CController { public function actions() { return array( 'service'=>array( 'class'=>'CWebServiceAction', 'classMap'=>array( 'Post'=>'Post', // or simply 'Post' ), ), ); } ...... }
透過實作IWebServiceProvider接口,sevice provider可以攔截遠端方法呼叫。在IWebServiceProvider::beforeWebMethod ,sevice provider可以獲得目前CWebService實例和透過CWebService::methodName請求的方法的名字 。它可以傳回假如果遠端方法出於某種原因不應被引用(例如:未經授權的存取) 。
以上就是Yii框架官方指南系列47-專題:Web Service的內容,更多相關內容請關注PHP中文網(www.php.cn)!