yii2入门之——如何写一个行为类

跨世纪少年 4月前 223

导语

最近因为公司项目需要第一次接解yii2框架,今天把yii2的行为使用作

一个简单的记录。

yii2行为的一个详细的介绍说明请参考点这里传送

yii2行为可以作用于全局也可以作用于具体某个控制器方法上,本文以作用于全局的行为为例,作用于控制器方法的行为写法也类似。

一、作用于全局的行为

我以项目中用到的验证登录行为作为示例,因为这是一个后台管理项目,任何方法都需要登录后才能进行操作,所以我们把登录验证写到了行为里。

1、配置文件加入行为配置

在配置文件的 components 中加入行为配置;

 'components' => [
    ....... // 省略各种其他配置
    // 我们加入的行为配置
    'as validateLogin' => [     // 指定自己写的行为类     
        'class' => 'app\components\behaviors\ValidateLoginBehavior',     
        'optional' => [ // 配置例外项(不受验证限制)       
            'route' => [ // 例外的路由
                'site/index', // 首页还是要不需要验证就可以查看(没问题)         
                'houtai/v1/user/login' // 登录界面还是需要可以打开的(没问题)       
            ],       
            'module' => [ // 例外module为了能使用yii自带的gii功能         
                'gii', // gii功能还想用,上线后可以去掉(能理解)         
                'web' // 也许后续会有web项目(很正常)       
            ],       
            'controller' => [ // 或者会有具体到某个方法的(为了灵活)
            
            ]     
        ]   
    ] 
 ]

2、开始写行为类

新建在第一步 class 里指定的行为类:ValidateLoginBehavior.php

我的在components/behaviors目录下

 'beforeAction'];
    }    /**
     * event handle function
     *
     * @return bool true|false
     */
    public function beforeAction($event){        if (!$this->isOptional()) {
            Yii::$app->response->format = 'json';  //以json格式返回
            self::authenticate();
        }        return true;
    }    /**
     * 检查是否需要登录
     *
     * @return boolean true|false
     */
    public function isOptional(){

		$pre_module = '';
        $routes = isset($this->optional['route']) ? $this->optional['route'] : [];
        $modules = isset($this->optional['module']) ? $this->optional['module'] : [];
        $controllers = isset($this->optional['controller']) ? $this->optional['controller'] : [];

        $current_route = Yii::$app->requestedRoute;
		$current_module = Yii::$app->controller->module->id;		if(isset(Yii::$app->controller->module->module->id)){
			$pre_module = Yii::$app->controller->module->module->id;
		}		//$pre_module = Yii::$app->controller->module->module->id ?? '';  //php7.0写法
        $current_controller = Yii::$app->controller->id;        return (in_array($current_module, $modules) || in_array($pre_module, $modules) ||
           in_array($current_route, $routes) || in_array($current_controller, $controllers));
    }    /**
	 * 验证用户的登录的access_token是否正确可用
     */
    private function authenticate(){

    	$auth_header = Yii::$app->request->getHeaders()->get('Authorization');        if($auth_header && preg_match('/^Dusnoob\s+(.*?)$/', $auth_header, $matches)){
            $access_token = $matches[1];
            $result = AccessTokenHelper::decrypt($access_token);            if(!$result){                throw new UnauthorizedHttpException('You are requesting with an invalid login credential.');
            }            if($result['expired'] < time()){                throw new UnauthorizedHttpException('Login credential is expired.');
            }
			$user = Admin::findOne(['id'=>$result['id'],'is_del'=>0]);			if(!$user){				throw new UnauthorizedHttpException('User is not exist or defriend.');
			}			$this->setUserIdentity($result);

        }else{            throw new UnauthorizedHttpException('You are requesting with an invalid login credential.');
        }
    }	/**
	 * 设置用户身份
	 * @param array $result
	 */
	private function setUserIdentity($result){
		$identity = new UserIdentity();
		$identity->setAttributes($result);
		Yii::$app->user->setIdentity($identity);
	}
}

经过上面处理后,就可以实现全局判断前端的请求是否需要通过登录验证才能得到返回

二、作用于控制器方法的行为

你也可以把行为绑定到某个控制器上触发;

只需要在相应的控制器上作行为的绑定即可,

/**
 * @inheritdoc
 */public function behaviors(){
    $behaviors = parent::behaviors();    return ArrayHelper::merge([
	['class'=>VisitStatisticLogBehavior::className()],
    ],$behaviors);
}

最新回复 (0)
    • 都市菜鸟网
      2
        立即登录 立即注册 
返回
发新帖