标签:反射 font 失败 ons mode ret pre ESS ==
Yii依靠文档注解(doc comments)和类反射(class
reflection)来识别哪个方法能够被远程调用,包括他们的參数和返回值,但眼下仅仅能返回字符串,不能返回数组,若返回数组,则为"array";故我将返回值转换为json字符串再返回.
1. 定义Service Provider,server端文件代码,WebServerController.php
<?php
/******************************
* @author sara zhou
* create time 2014-06-25 16:00:00
* YII框架API接口端的server (基于Webservice的接口server端)
* 注意php.ini开启soap扩展:extension=php_soap.dll
*******************************
*/
class WebServerController extends CController{
/**
* @var array error
* @soap
*/
public $error=array(
‘0000‘=>‘操作成功‘,
‘0001‘=>‘操作失败‘,
‘0002‘=>‘參数param错误‘,
‘1001‘=>‘用户不存在‘,
);
public function actions()
{
return array(
‘approval‘=>array(
‘class‘=>‘CWebServiceAction‘,
‘classMap‘=>array(//classMap事实上仅仅要是相应的Model即可。比方这里的ApiUser
‘ApiUser‘,
),
),
);
}
/**
* @desc get_user_info()获取用户信息,代码凝视里包括 * @soap,则 此方法可通过soap訪问到
* @param array
* @return array the ApiUser info 也必须和Model名称一致
* @soap
*/
public function get_user_info($param_arr){
$param_arr=CJSON::decode($param_arr);
$param[‘user_name‘]=htmlspecialchars(@$param_arr[‘user_name‘]);
$param[‘request_id‘]=intval(@$param_arr[‘request_id‘]);
//加入API訪问日志信息
$apiLog=new ApiLog1();
$log_id=$apiLog->insert_api_log($param[‘request_id‘], CJSON::encode($param));
$res=array(‘user_name‘=>$param[‘user_name‘],‘user_email‘=>$param[‘user_email‘]);
//验证相关參数是否符合要求
if (empty($param[‘user_name‘])) {
$res[‘response_time‘]=date("YmdHis");
$res[‘error_code‘]=‘0002‘;
$res[‘error_msg‘]=str_replace(‘param‘,‘user_name‘,$this->error[‘0002‘]);
//更新API訪问日志信息
$apiLog->update_api_log($log_id, CJSON::encode($res),@$res[‘response_time‘], @$res[‘error_code‘],$res[‘error_msg‘]);
return CJSON::encode($res);
}
if ($param[‘request_id‘]<=0) {
$res[‘response_time‘]=date("YmdHis");
$res[‘error_code‘]=‘0002‘;
$res[‘error_msg‘]=str_replace(‘param‘,‘request_id‘,$this->error[‘0002‘]);
//更新API訪问日志信息
$apiLog->update_api_log($log_id, @$res,@$res[‘response_time‘], @$res[‘error_code‘],$res[‘error_msg‘]);
return $res;
}
$user=new User();
$user_info=$user->getUserInfo($param[‘user_name‘]);
if ($user_info)
{
$res[‘error_code‘]="1003";
}
else
{
$res[‘error_code‘]="0000";
}
$res[‘response_time‘]=date("YmdHis");
$res[‘error_msg‘]=$this->error[$res[‘error_code‘]];
//更新API訪问日志信息
$apiLog->update_api_log($log_id, @$res,@$res[‘response_time‘], @$res[‘error_code‘],$res[‘error_msg‘]);
return $res;
}
/*
* 代码凝视里不包括 * @soap,则无法通过soap方式訪问
*/
public function test($param_arr){
$arr = array(
‘user_id‘=>$param_arr[‘user_id‘],
‘request_id‘=>$param_arr[‘request_id‘],//‘请求号‘,
‘request_time‘=>$param_arr[‘request_time‘],//‘请求时间‘
);
return true;
}
}
保存WebServerController.php文件,浏览器输入地址:http://localhost/api/webServer/approval,将得到一个包括大量XML格式的内容,实际上他就是上面Web Service定义的WSDL.XML内容中,能够看到serverAPI接口中开放的方法
2.client调用(此实例为phpclient调用实例,可使用其它语言)
<?php
/******************************
* @author sara zhou
* create time 2014-06-25 16:00:00
* YII框架API接口端的client调用实例 (基于Webservice的接口server端)
* 注意php.ini开启soap扩展:extension=php_soap.dll
*******************************
*/
class ClientController extends CController
{
public function actionGetUserInfo(){
//制定server訪问地址
$client = new SoapClient(‘http://localhost/api/webServer/approval‘);
//调用server接口方法 get_user_info()获取用户信息;因为接口是传json数组,故这里以传json格式传递
$res= $client->get_user_info(‘{"user_ame":"123","request_id":"23123"}‘);
var_dump($res);
}
}
?>
</pre><p></p><p><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; font-size:14px; line-height:25.200000762939453px">3.用户模型层文件 User.php => model</span></p><p><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; font-size:14px; line-height:25.200000762939453px">?</span></p><pre code_snippet_id="420941" snippet_file_name="blog_20140707_3_9312600" name="code" class="php"><?php
/**
* 用户模型
*
* @author Sara Zhou
*/
class User extends CActiveRecord
{
//Model里要公开的变量,须要用以下的形式标明
/**
* @var integer user_id
* @soap
*/
public $id;
/**
* @var string post title
* @soap
*/
public $title;
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function tableName()
{
return ‘user‘;
}
public static function getUserInfo($user_name){
return User::model()->findbyPk($user_name);
}
}
model里要公开的变量,须要用以下的形式标明4.请求模型层的日志API文件,ApiLog.php ?=> model
<?php
/**
*
* @author Sara zhou
* @create 2014-06-11
* @desc:主要用于记录API訪问日志
*/
class ApiLog extends CActiveRecord
{
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* @return string the associated database table name
*/
public function tableName()
{
return ‘api_log‘;
}
/*
* insert_api_log()记录API请求日志
* @param $require_no
* @param $require_param
*/
public function insert_api_log($require_no,$require_param){
//仅仅做插入
$binsd = array(
‘require_no‘=> $require_no,
‘require_url‘=> $_SERVER[‘HTTP_HOST‘] .$_SERVER[‘REQUEST_URI‘],
‘require_param‘=> $require_param,
‘require_time‘=> date(‘Y-m-d H:i:s‘,$_SERVER[‘REQUEST_TIME‘]),
‘require_method‘=> $_SERVER[‘REQUEST_METHOD‘],
‘server_protocol‘=> $_SERVER[‘SERVER_PROTOCOL‘],
‘create_time‘=> date(‘Y-m-d H:i:s‘,$_SERVER[‘REQUEST_TIME‘]),
);
if ($_SERVER["HTTP_X_FORWARDED_FOR"]=="")
{
$bind[‘require_ip‘]=$_SERVER[‘REMOTE_ADDR‘] .‘:‘.$_SERVER[‘REMOTE_PORT‘];
}
else
$bind[‘require_ip‘]=$_SERVER["HTTP_X_FORWARDED_FOR"].‘:‘.$_SERVER[‘REMOTE_PORT‘];
$this->setAttributes($binsd, false);
$this->save();
return $this->attributes[‘id‘];
}
/*
* update_api_log()更新API请求日志
* @param $log_id
* @param $response_param
* @param $response_time
* @param $error_code
* @param $error_msg
*/
public function update_api_log($log_id,$response_param,$response_time,$error_code,$error_msg){
//仅仅做更新
$sql = "UPDATE api_log set response_param=:response_param,response_time=:response_time,error_code=:error_code,error_msg=:error_msg where id=:id";
$command=Yii::app()->db->createCommand($sql);
$bind = array(
‘id‘=> $log_id,
‘response_param‘=> $response_param,
‘response_time‘=> $response_time,
‘error_code‘=> $error_code,
‘error_msg‘=> $error_msg,
);
return $command->execute($bind);
}
}
5.拦截远程方法调用(Intercepting Remote Method Invocation)?
通过实现[IWebServiceProvider]接口。能够拦截全部方法,在[IWebServiceProvider::beforeWebMethod]。这个provider能够获取当前CWebService实例,并通过CWebService::methodName来获取当前请求的方法名。它能够返回false,假设这个远程方法因某些原因(比方未经授权的訪问)不应被调用
6.注意:
a. server要打开soap功能。在phpinfo里搜soap,假设已经打开了的话有个大标题就是SOAP
b. classMap事实上仅仅要是相应的Model即可,比方这里的ApiUser。
c. 代码凝视里* @return ApiUser[] the apiUser records ApiUser[]也必须和Model名称一致
d. 代码凝视里* @soap 这个也不能少,不然无法通过soap方式訪问,想不到凝视里还有这么多文章
e. 假设controller里有accessRules的话。得设定訪客就能够訪问getPredictions()
f. Model里要公开的变量,须要用以下的形式标明:
/**
???? * @var integer UID of this record
???? * @soap
???? */
??? public $uid;
YII框架之soap协议的配置跟使用(Webservice)
标签:反射 font 失败 ons mode ret pre ESS ==
原文地址:https://www.cnblogs.com/xfgnongmin/p/10807501.html