在yii中soap协议的配备和使用
在yii中soap协议的配置和使用
作者:zccst
1,定义Service Provider
Yii依靠文档注解(doc comments)和类反射(class reflection)来识别哪个方法可以被远程调用,包括他们的参数和返回值。
我们定义服务器端的类,继承CController,如下面的例子所示:
在上面的例子中,我们定义了方法getPrice(使用@soap)作为一个可供远程调用的API,并且通过文档注解(doc comments)来指定参数和返回值的数据类型。
批注:后面会讲数据类型可分为基本数据类型和复合数据类型。
2,定义 Web Service Action
既然前面已知服务器端类是继承自CController,所以需要定义一个action,将服务暴露出去。继续上面的例子,我们仅仅在StockController增加如下代码:
至此,如果我们访问地址:http://hostname/path/to/index.php?r=stock/quote
我们将得到一个包含大量XML格式的内容,实际上它就是上面Web Service定义的WSDL。
批注:缺省情况下,CWebServiceAction默认当前controller就是Service Provider,这就是为什么上面直接在StockController里定义getPrice方法。
3,在客户端调用:(可以使用多种语言)
4,关于参数和返回值的数据类型
在实际应用中,参数和返回值的数据类型可分为基本数据类型和复合数据类型。
(1)基本类型数据
string , integer , float, boolean, date, time, datetime, array , object, mixed
(2)复合类型数据
如果是复合数据类型,则复合数据类型会通过类的形式表示,这时它的每一个public的数据项都需要使用@soap来进行文档注解(doc comments)。例如:
需要注意的是,如果想让client端收到复合类型数据,除了上面给出的类定义外,还需要在Service Provider的actions方法里增加配置项classMap=>array('outsource_header')。如下面所示:
此外,复合数据类型也可以使用数组(Array),通过[]向基本数据类型或复合数据类型的末尾追加的方式。例如,
该实例,调用getPosts方法时,将返回一个数组。
5,拦截远程方法调用(Intercepting Remote Method Invocation)
通过实现[IWebServiceProvider]接口,可以拦截所有方法,在[IWebServiceProvider::beforeWebMethod],这个provider可以获取当前CWebService实例,并通过CWebService::methodName来获取当前请求的方法名,它可以返回false,如果这个远程方法因某些原因(比如未经授权的访问)不应被调用。
作者: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,如果这个远程方法因某些原因(比如未经授权的访问)不应被调用。