在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,如果这个远程方法因某些原因(比如未经授权的访问)不应被调用。

如果您觉得本文的内容对您的学习有所帮助,您可以微信:
[img]http://dl2.iteye.com/upload/attachment/0109/0668/fb266dfa-95ca-3d09-b41e-5f04a19ba9a1.png[/img]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值