首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > XML SOAP >

在yii中soap协议的配备和使用

2012-12-24 
在yii中soap协议的配置和使用作者:zccst1,定义Service ProviderYii依靠文档注解(doc comments)和类反射(cl

在yii中soap协议的配置和使用
作者:zccst

1,定义Service Provider
Yii依靠文档注解(doc comments)和类反射(class reflection)来识别哪个方法可以被远程调用,包括他们的参数和返回值。

我们定义服务器端的类,继承CController,如下面的例子所示:

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}}

在上面的例子中,我们定义了方法getPrice(使用@soap)作为一个可供远程调用的API,并且通过文档注解(doc comments)来指定参数和返回值的数据类型。

批注:后面会讲数据类型可分为基本数据类型和复合数据类型。

2,定义 Web Service Action
既然前面已知服务器端类是继承自CController,所以需要定义一个action,将服务暴露出去。继续上面的例子,我们仅仅在StockController增加如下代码:
class StockController extends CController{/***********  增加  start  **************/public function actions(){return array('quote'=>array('class'=>'CWebServiceAction'),);}/***********  增加  end  **************//*** @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}}



至此,如果我们访问地址:http://hostname/path/to/index.php?r=stock/quote
我们将得到一个包含大量XML格式的内容,实际上它就是上面Web Service定义的WSDL。


批注:缺省情况下,CWebServiceAction默认当前controller就是Service Provider,这就是为什么上面直接在StockController里定义getPrice方法。


3,在客户端调用:(可以使用多种语言)
$client = new SoapClient('http://hostname/path/to/index.php?r=stock/quote');echo $client->getPrice('GOOGLE');//运行上面的脚本,通过Web或命令行方式,可以得出结果:350



4,关于参数和返回值的数据类型
在实际应用中,参数和返回值的数据类型可分为基本数据类型和复合数据类型。

(1)基本类型数据
string , integer , float, boolean, date, time, datetime, array , object, mixed

(2)复合类型数据
如果是复合数据类型,则复合数据类型会通过类的形式表示,这时它的每一个public的数据项都需要使用@soap来进行文档注解(doc comments)。例如:
class outsource_header {/** * @var string 访问密钥, a和b之间的访问控制 * @soap */public $token;/** * @var integer 外包单号 * @soap */public $id;/** * @var string 该外包单对应的机房名称 * @soap */public $idc_name;/** * @var outsource_handler 处理人信息 * @soap */public $handler;// 处理人信息}

需要注意的是,如果想让client端收到复合类型数据,除了上面给出的类定义外,还需要在Service Provider的actions方法里增加配置项classMap=>array('outsource_header')。如下面所示:
class XXController extends CController{public function actions(){return array('service'=>array('class'=>'CWebServiceAction',//增加  classMap 配置项'classMap'=>array('outsource_header',),),);}}





此外,复合数据类型也可以使用数组(Array),通过[]向基本数据类型或复合数据类型的末尾追加的方式。例如,
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;public static function model($className=__CLASS__){return parent::model($className);}}

该实例,调用getPosts方法时,将返回一个数组。


5,拦截远程方法调用(Intercepting Remote Method Invocation)
通过实现[IWebServiceProvider]接口,可以拦截所有方法,在[IWebServiceProvider::beforeWebMethod],这个provider可以获取当前CWebService实例,并通过CWebService::methodName来获取当前请求的方法名,它可以返回false,如果这个远程方法因某些原因(比如未经授权的访问)不应被调用。

热点排行