控制器类,所有控制器的基类,用于调用模型和布局,输出到视图

 namespace yii\base;

 use Yii;

 /**
  * Controller is the base class for classes containing controller logic.
  * 控制器,是所用控制器类的基类
  *
  * @property Module[] $modules  只读属性  当前控制器的所有模块
  *
  * @property string $route  (module ID, controller ID and action ID)  当前请求的路径  只读属性 可以获取到请求的路径
  *
  * @property string $uniqueId  以module ID(如果有的话) 为前缀的controller ID  应该是唯一标识的作用
  *
  * @property View|\yii\web\View $view 视图 object 用来传递视图或视图文件.
  *
  * @property string $viewPath 包含当前控制器的视图目录.
  *
  * @author Qiang Xue <qiang.xue@gmail.com>
  * @since 2.0
  */
 class Controller extends Component implements ViewContextInterface
 {
     /**
      * @event ActionEvent an event raised right before executing a controller action.
      * You may set [[ActionEvent::isValid]] to be false to cancel the action execution.
      * 在执行beforeAction方法时触发的事件,如果对事件的isValid属性设置为false,将取消action的执行
      */
     const EVENT_BEFORE_ACTION = 'beforeAction';
     /**
      * @event ActionEvent an event raised right after executing a controller action.
      * 在执行afterAction方法是触发的事件
      */
     const EVENT_AFTER_ACTION = 'afterAction';

     /**
      * @var string the ID of this controller.
      * 控制器id,
      */
     public $id;
     /**
      * @var Module $module the module that this controller belongs to.
      * 所属模块
      */
     public $module;
     /**
      * @var string the ID of the action that is used when the action ID is not specified
      * in the request. Defaults to 'index'.
      * 控制器中默认动作,默认为index
      */
     public $defaultAction = 'index';
     /**
      * @var string|boolean the name of the layout to be applied to this controller's views.
      * This property mainly affects the behavior of [[render()]].
      * Defaults to null, meaning the actual layout value should inherit that from [[module]]'s layout value.
      * If false, no layout will be applied.
      * 布局文件,如果设置为false,则不使用布局文件
      */
     public $layout;
     /**
      * @var Action the action that is currently being executed. This property will be set
      * by [[run()]] when it is called by [[Application]] to run an action.
      * 当前下面执行的action,可在事件中根据这个action来执行不同的操作
      */
     public $action;

     /**
      * @var View the view object that can be used to render views or view files.
      * 视图对象,用来定义输出的视图文件
      */
     private $_view;
     /**
      * @var string the root directory that contains view files for this controller.
      */
     private $_viewPath;

     /**
      * @param string $id 当前控制器的ID
      * @param Module $module 当前控制器的模块
      * @param array $config 初始化对像时的配置文件
      */
     public function __construct($id, $module, $config = [])
     {
         //初始化指定控制器id,模块,根据配置文件初始化控制器对象
         $this->id = $id;
         $this->module = $module;
         parent::__construct($config);
     }

     /**
      * Declares external actions for the controller.
      * 定义action   声明控制器的外部操作
      * This method is meant to be overwritten to declare external actions for the controller.
      * It should return an array, with array keys being action IDs, and array values the corresponding
      * action class names or action configuration arrays. For example,
      * 这个用来指定独立的action,返回格式为name-value的数组,name为action的id,value为action类的实现,如:
      *
      * ```php
      * return [
      *     'action1' => 'app\components\Action1',
      *     'action2' => [
      *         'class' => 'app\components\Action2',
      *         'property1' => 'value1',
      *         'property2' => 'value2',
      *     ],
      * ];
      * ```
      *
      * [[\Yii::createObject()]] will be used later to create the requested action
      * using the configuration provided here.
      * 这个主要是用于在子类中重写
      */

     public function actions()
     {
         return [];
     }

     /**
      * Runs an action within this controller with the specified action ID and parameters.
      * If the action ID is empty, the method will use [[defaultAction]].
      * $id 为action的id,也就是操作的名称,如定义的actionIndex,那么id就为Index。
      * 如果没有定义 action ID,就会调用默认的操作,例如常用的index
      *
      * @param string $id 操作id,也就是操作名
      * @param array $params the parameters (name-value pairs) to be passed to the action.
      * @return mixed the result of the action.
      * @throws InvalidRouteException if the requested action ID cannot be resolved into an action successfully.
      * @see createAction()
      */
     public function runAction($id, $params = [])
     {
         //创建action
         $action = $this->createAction($id);
         if ($action === null) {
             //创建action失败,抛出异常
             throw new InvalidRouteException('Unable to resolve the request: ' . $this->getUniqueId() . '/' . $id);
         }
         //写入trace信息
         Yii::trace('Route to run: ' . $action->getUniqueId(), __METHOD__);

         if (Yii::$app->requestedAction === null) {
             Yii::$app->requestedAction = $action;//不知道这个是干嘛用的0.0
         }

         $oldAction = $this->action;//将action中的信息保存到oldAction
         $this->action = $action; //将当前的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 && $this->beforeAction($action)) {//判断当前控制器中beforeAction
             // 由生成的action对象来执行runWithParams方法
             $result = $action->runWithParams($params);
                 //执行完后,再执行afterAction方法
             $result = $this->afterAction($action, $result);

              //执行所有父模块的afterAction
             foreach ($modules as $module) {
                 /* @var $module Module */
                 $result = $module->afterAction($action, $result);
             }
         }
         $this->action = $oldAction;//有什么用呢?,看完后面的在回头看吧

         return $result;
     }

Yii源码阅读笔记(十)的更多相关文章

  1. Yii源码阅读笔记(一)

    今天开始阅读yii2的源码,想深入了解一下yii框架的工作原理,同时学习一下优秀的编码规范和风格.在此记录一下阅读中的小心得. 每个框架都有一个入口文件,首先从入口文件开始,yii2的入口文件位于we ...

  2. Yii源码阅读笔记(三十五)

    Container,用于动态地创建.注入依赖单元,映射依赖关系等功能,减少了许多代码量,降低代码耦合程度,提高项目的可维护性. namespace yii\di; use ReflectionClas ...

  3. Yii源码阅读笔记(三十四)

    Instance类, 表示依赖注入容器或服务定位器中对某一个对象的引用 namespace yii\di; use Yii; use yii\base\InvalidConfigException; ...

  4. Yii源码阅读笔记(三十二)

    web/Application类的注释,继承base/Application类,针对web应用的一些处理: namespace yii\web; use Yii; use yii\base\Inval ...

  5. Yii源码阅读笔记(三十)

    Widget类是所有小部件的基类,开始,结束和渲染小部件内容的方法的注释: namespace yii\base; use Yii; use ReflectionClass; /** * Widget ...

  6. Yii源码阅读笔记(二十九)

    动态模型DynamicModel类,用于实现模型内数据验证: namespace yii\base; use yii\validators\Validator; /** * DynamicModel ...

  7. Yii源码阅读笔记(二十八)

    Yii/web中的Controller类,实现参数绑定,启动csrf验证功能,重定向页面功能: namespace yii\web; use Yii; use yii\base\InlineActio ...

  8. Yii源码阅读笔记(二十六)

    Application 类中设置路径的方法和调用ServiceLocator(服务定位器)加载运行时的组件的方法注释: /** * Handles the specified request. * 处 ...

  9. Yii源码阅读笔记(二十四)

    Module类中获取子模块,注册子模块,实例化控制器,根据路由运行指定控制器方法的注释: /** * Retrieves the child module of the specified ID. * ...

  10. Yii源码阅读笔记(二十二)

    Module类,属性的注释和构造函数的注释: <?php /** * @link http://www.yiiframework.com/ * @copyright Copyright (c) ...

随机推荐

  1. IEEE754测试-软件

    为满足硬件开发的同事验证从传感器采集到的数据是否正确,也为了方便我自己, 随手做了这个小东西,主要涉及浮点数的存储问题!

  2. Hark的数据结构与算法练习之计数排序

    算法说明 计数排序属于线性排序,它的时间复杂度远远大于常用的比较排序.(计数是O(n),而比较排序不会超过O(nlog2nJ)). 其实计数排序大部分很好理解的,唯一理解起来很蛋疼的是为了保证算法稳定 ...

  3. login控件重载登陆方法

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

  4. Github排行榜

    http://githubranking.com/ 中国区开发者排行榜: http://githubrank.com/ 也可以在官网查询: https://github.com/search?q=st ...

  5. js:工具库-highcharts.js

    主要用于方便绘制图标,注意是需要付费的: 相关连接: 官网 中文网 祛除自带标识的代码: credits: { enabled: false //remove the logo and button ...

  6. BZOJ1707 : [Usaco2007 Nov]tanning分配防晒霜

    S向每头奶牛连边,容量1 每个防晒霜向T连边,容量cover 每头奶牛向SPF在自己范围内的防晒霜连边,容量inf 用线段树优化建图跑最大流即可. #include<cstdio> con ...

  7. 【BZOJ】1821: [JSOI2010]Group 部落划分 Group(最小生成树+贪心)

    http://www.lydsy.com:808/JudgeOnline/problem.php?id=1821 这题裸题. 本题要求最短距离最长,很明显,我们排序. 这里存在贪心,即我们把边权最小的 ...

  8. Redis中7种集合类型应用场景

    StringsStrings 数据结构是简单的key-value类型,value其实不仅是String,也可以是数字.使用Strings类型,你可以完全实现目前 Memcached 的功能,并且效率更 ...

  9. HTML5 video 视频标签全属性详解

    现在如果要在页面中使用video标签,需要考虑三种情况,支持Ogg Theora或者VP8(如果这玩意儿没出事的话)的(Opera.Mozilla.Chrome),支持H.264的(Safari.IE ...

  10. javascript大全

    事件源对象 event.srcElement.tagName event.srcElement.type 捕获释放 event.srcElement.setCapture(); event.srcEl ...