木子炜培先生

⑴2017底=>(年薪15万)=>31岁 ⑵2018=》(生产生活用品)并且年薪20万=>32岁 ⑶2019=>年薪30万=>把小作坊升级为工厂=>33岁 ⑷2020=>再开一个食品工厂

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

相关文章http://www.tuicool.com/articles/JvM73mn

Yii2.0源码分析之——控制器文件分析(Controller.php)创建动作、执行动作

1yii请求流程

url请求=>application获取request信息,request=>urlManager解析出route,=>Module中根据route来创建controller并处理request。 

 2

Yii中总共有三种控制器类

base\Controller.php        这个是下面两个的基类
console\Controller.php   这个是控制台控制器
web\Controller.php        这个是web控制器

1、和action相关的函数 

 执行路由:public function run($route, $params = [])

/*
* route值即可以为当前controller中的action id,
* 
* 也可为module id/controller id/action id/这种格式
* 如果以“/”开头,将于application来处理,否则,用控制器所属模块来处理
*/

 

public function run($route, $params = [])
{
    //先判断route中有没有“/”
    $pos = strpos($route, '/');
    if ($pos === false) {
        //如果没有“/”,则为action id,直接调用runAction来执行这个action。如:index
        return $this->runAction($route, $params);
    } elseif ($pos > 0) {
        //如果“/”在中间,由当前的模块来处理这个route。如:test/index
        return $this->module->runAction($route, $params);
    } else {
        //如果以“/”开头,则用当前的应用程序来处理这个route。如:/test/index;
        return Yii::$app->runAction(ltrim($route, '/'), $params);
    }
}
View Code

执行动作:public function runAction($id, $params = [])

/*
* $id 为action的id,如定义的actionIndex,那么id就为Index。
* 
*/
public function runAction($id, $params = [])
{
    //创建action
    $action = $this->createAction($id);
    if ($action === null) {
        throw new InvalidRouteException('Unable to resolve the request: ' . $this->getUniqueId() . '/' . $id);
    }

    Yii::trace("Route to run: " . $action->getUniqueId(), __METHOD__);

    if (Yii::$app->requestedAction === null) {
        Yii::$app->requestedAction = $action;
    }

    $oldAction = $this->action;
    $this->action = $action;

    //用来保存当前控制器的所有父模块,顺序为由子模块到父模块
    $modules = [];
    $runAction = true;

    /*
     * 获取当前控制器的所以的模块,并执行每个模块的beforeAction来检查当前的action是否可以执行,
     * 注意:getModules返回的数组顺序为:从父模块到子模块,
     * 所以在执行beforeAction的时候,先检查最外层的父模块,然后检查子模块。
     * 
     * 然而在执行afterAction的时候,顺序就反过来了,先执行子模块,最后执行父模块。
     * 
     */
    foreach ($this->getModules() as $module) {
        if ($module->beforeAction($action)) {
        array_unshift($modules, $module);
        } else {
        $runAction = false;
        break;
        }
    }

    $result = null;

    //如果所以的父模块都满足执行的条件
    if ($runAction) {
        /*
         * 再判断当前控制器中是beforeAction,
         * 最后由生成的action对象来执行runWithParams方法
         * 
         * 执行完后,再执行afterAction方法
         */
        if ($this->beforeAction($action)) {
        $result = $action->runWithParams($params);
        $result = $this->afterAction($action, $result);
        }
    }

    //执行所有父模块的afterAction
    foreach ($modules as $module) {
        /** @var Module $module */
        $result = $module->afterAction($action, $result);
    }

    $this->action = $oldAction;

    return $result;
}
View Code

创建动作 public function createAction($id)

//由action id来创建action对象
public function createAction($id)
{
        //使用默认的action id ,默认值为:index
        if ($id === '') {
            $id = $this->defaultAction;
        }

        $actionMap = $this->actions();
        if (isset($actionMap[$id])) {
                //如果在actions方法中指定了独立的动作,则直接使用此动作。
            return Yii::createObject($actionMap[$id], [$id, $this]);
        } elseif (preg_match('/^[a-z0-9\\-_]+$/', $id) && strpos($id, '--') === false && trim($id, '-') === $id) {
                /*
                 * action id由:a到z、0到9、\、-、_ 这五种字符组成,
                 * 并且不能包含“--”
                 * 并且不能以“-”为开头或结尾
                 * 
                 * 先以“-”把id分隔为数组,再以“ ”连接到字符串,把每个单词首字母大写,最后把“ ”去掉,并和"action"连接
                 * 如;
                 * 1、new-post-v-4
                 * 2、['new','post','v','4']
                 * 3、new post v 4
                 * 4、New Post V 4
                 * 5、NewPostV4
                 * 6、actionNewPostV4
                 */
            $methodName = 'action' . str_replace(' ', '', ucwords(implode(' ', explode('-', $id))));
            if (method_exists($this, $methodName)) {
                    /*
                     * 如果当前控制器中存在这个actionXXX方法,
                     * 再通过反射生成方法,再次检查一遍,最后生成InlineAction
                     */
                $method = new \ReflectionMethod($this, $methodName);
                if ($method->getName() === $methodName) {
                    return new InlineAction($id, $this, $methodName);
                }
            }
        }

        return null;
}
View Code

 

posted on 2017-03-04 15:16  木子炜培先生  阅读(212)  评论(0编辑  收藏  举报