Yii2.0源码分析之——Web控制器文件分析(yii\web\Controller.php)

十度 Yii2 2015年11月30日 收藏

这个控制器大体也分三部分

  • action相关功能
  • render相关功能
  • 常用response简写


1、action相关功能

action中绑定参数功能:public function bindActionParams($action, $params)

/*
* 这个是基类的 action中绑定参数功能的实现
* 
* 根据action中定义的参数,从$_GET中取对应的值,
* 如果没有,则报错
*/
public function bindActionParams($action, $params)
{
        /*
         * 先通过反射得到动作action的方法信息
         * 
         * 有两种action,
         * 一种是Yii提供的InlineAction,我们在控制器里面定义的actionXXX都是这种类型
         * 另外一个就是独立action,直接继承自Action类,并实现里面的run方法。
         */
        if ($action instanceof InlineAction) {
            $method = new \ReflectionMethod($this, $action->actionMethod);
        } else {
            $method = new \ReflectionMethod($action, 'run');
        }
        $args = [];
        $missing = [];
        $actionParams = [];
        foreach ($method->getParameters() as $param) {
            //获取在action中定义的参数的名称。
            //如action定义为:actionIndex($x,$y=5)
            $name = $param->getName();
            //如果action中定义 的参数存在于$_GET中
            if (array_key_exists($name, $params)) {
                if ($param->isArray()) {
                    /*
                     * 如果参数是数组类型的,
                     * 如果从$_GET中取得的数据是数组,返回
                     * 否则包装到数组
                     */
                    $args[] = $actionParams[$name] = is_array($params[$name]) ? $params[$name] : [$params[$name]];
                } elseif (!is_array($params[$name])) {
                    /*
                     * 如果不是数组,直接返回$_GET中对应的结果
                     */
                    $args[] = $actionParams[$name] = $params[$name];
                } else {
                    throw new BadRequestHttpException(Yii::t('yii', 'Invalid data received for parameter "{param}".', [
                        'param' => $name,
                    ]));
                }
                unset($params[$name]);            
            } elseif ($param->isDefaultValueAvailable()) {
                //如果默认有默认值。
                $args[] = $actionParams[$name] = $param->getDefaultValue();
            } else {
                //action中定义的参数没有在$_GET中找到。
                $missing[] = $name;
            }
        }
        //action中的参数有缺少,报异常
        if (!empty($missing)) {
            throw new BadRequestHttpException(Yii::t('yii', 'Missing required parameters: {params}', [
                'params' => implode(', ', $missing),
            ]));
        }
        $this->actionParams = $actionParams;
        return $args;
}

启动csrf验证功能

//这个重写基类的beforeAction
public function beforeAction($action)
{
        if (parent::beforeAction($action)) {
                //启动csrf验证功能
            if ($this->enableCsrfValidation && Yii::$app->errorHandler->exception === null && !Yii::$app->getRequest()->validateCsrfToken()) {
                throw new BadRequestHttpException(Yii::t('yii', 'Unable to verify your data submission.'));
            }
            return true;
        } else {
            return false;
        }
}

2、render相关功能

除了基类的几个render外,在这个里面还增加了一种对ajax请求的响应

/*
* 这个渲染的结棍用来作为ajax请求的的响应
* 这个方法和renderPartial类似,但这个返回的结果中会包含css/js以及其它在view中注册的文件。
*/
public function renderAjax($view, $params = [])
{
        return $this->getView()->renderAjax($view, $params, $this);
}

3、常用response简写

重定向
public function redirect($url, $statusCode = 302)
其中$url参数为

  • 别名url,如:"@yiifans.com"
  • 数组,如果为数组的话格式为[$route,.....name-value...],如:['site/index','id'=>5,'keyword'=>'test'],


不管哪种参数,都会在redirect内部用 Url::to() 来处理。

另外,如果传入的是相对的url,都会根据当前请求的host info 转换为绝对url,

返回首页

public function goHome()

后退

public function goBack($defaultUrl = null)

其中$defaultUrl为字符串或数组

刷新

public function refresh($anchor = '')