Yii框架2.0的控制器

控制器是继承[[yiiaseController]]类的对象,负责处理请求和生成响应。 具体来说,控制器从应用主体接管控制后会分析请求数据并传送到模型, 传送模型结果到视图,最后生成输出响应信息。

控制器是由一个或多个操作来组成的。

控制器的路由由 模型id(仅存在于控制器属于非应用的模块)、 控制器id、 操作id 组成。 

路由使用如下格式:

ControllerID/ActionID

如果属于模块下的控制器,使用如下格式:

ModuleID/ControllerID/ActionID

控制器ID

通常情况下,控制器用来处理请求有关的资源类型,因此控制器ID通常为和资源有关的名词。 例如使用article作为处理文章的控制器ID。
控制器ID应仅包含英文小写字母、数字、下划线、中横杠和正斜杠, 例如 article 和 post-comment 是真是的控制器ID,article?, PostComment, adminpost不是控制器ID。
控制器Id可包含子目录前缀,例如 admin/article 代表 [[yiiaseApplication::controllerNamespace|controller namespace]]控制器命名空间下 admin子目录中 article 控制器。 子目录前缀可为英文大小写字母、数字、下划线、正斜杠,其中正斜杠用来区分多级子目录(如 panels/admin)

控制器ID遵循以下规则衍生控制器类名:

将用正斜杠区分的每个单词第一个字母转为大写。注意如果控制器ID包含正斜杠,只将最后的正斜杠后的部分第一个字母转为大写;
去掉中横杠,将正斜杠替换为反斜杠;
增加Controller后缀;
在前面增加[[yiiaseApplication::controllerNamespace|controller namespace]]控制器命名空间.
下面为一些示例,假设[[yiiaseApplication::controllerNamespace|controller namespace]]控制器命名空间为 appcontrollers:

article 对应 appcontrollersArticleController;
post-comment 对应 appcontrollersPostCommentController; //此种情况为Comment的首字母大写,而它事中间的单词所以用一个中横线标识下。
admin/post-comment 对应 appcontrollersadminPostCommentController;
adminPanels/post-comment 对应 appcontrollersadminPanelsPostCommentController.

控制器部署

可通过配置 [[yiiaseApplication::controllerMap|controller map]] 来强制上述的控制器ID和类名对应, 通常用在使用第三方不能掌控类名的控制器上。
配置 应用配置 中的application configuration  web.php,如下所示:

[
    'controllerMap' => [
        // 用类名申明 "account" 控制器
        'account' => 'appcontrollersUserController',

        // 用配置数组申明 "article" 控制器
        'article' => [
            'class' => 'appcontrollersPostController',
            'enableCsrfValidation' => false,
        ],
    ],
]

默认控制器 : 框架默认的是 site 控制器,不过可以在 web.php里配置, 

[
    'defaultRoute' => 'main',
]

创建操作: 必须以 action开头的函数。操作方法的名字大小写敏感,ActonName 不会被认为事操作方法。

独立操作

独立操作通过继承[[yiiaseAction]]或它的子类来定义。 例如Yii发布的[[yiiwebViewAction]]和[[yiiwebErrorAction]]都是独立操作。
要使用独立操作,需要通过控制器中覆盖[[yiiaseController::actions()]]方法在action map中申明,如下例所示:

 1 public function actions()
 2 {
 3     return [
 4         // 用类来申明"error" 操作
 5         'error' => 'yiiwebErrorAction',
 6 
 7         // 用配置数组申明 "view" 操作
 8         'view' => [
 9             'class' => 'yiiwebViewAction',
10             'viewPrefix' => '',
11         ],
12     ];
13 }

如上所示, actions() 方法返回键为操作ID、值为对应操作类名或数组configurations 的数组。 和内联操作不同,独立操作ID可包含任意字符,只要在actions() 方法中申明.
为创建一个独立操作类,需要继承[[yiiaseAction]] 或它的子类,并实现公有的名称为run()的方法, run() 方法的角色和操作方法类似,例如:

namespace appcomponents;
use yiiaseAction;
class HelloWorldAction extends Action
{
    public function run()
    {
        return "Hello World";
    }
}

操作参数

内联操作的操作方法和独立操作的 run() 方法可以带参数,称为操作参数。 参数值从请求中获取,对于[[yiiwebApplication|Web applications]]网页应用, 每个操作参数的值从$_GET中获得,参数名作为键;

默认操作:

不做处理的话,默认操作就是 index操作,当然也可以修改,直接覆盖父类的 $defaultAction 变量就可以了,例如:

namespace appcontrollers;
use yiiwebController;
class SiteController extends Controller
{
    public $defaultAction = 'home';

    public function actionHome()
    {
        return $this->render('home');
    }
}

控制器里的createUrl 和 createAbsoluteUrl方法已经删除了,现在使用的`yiihelpersUrl::toRoute`  来代替,也可以用 Yii::$app->getUrlManager()->createUrl($params),实际都是用UrlManager类的createUrl方法来实现的。 

控制器生命周期

处理一个请求时,应用主体 会根据请求路由创建一个控制器,控制器经过以下生命周期来完成请求:

  1. 在控制器创建和配置后,[[yiiaseController::init()]] 方法会被调用。
  2. 控制器根据请求操作ID创建一个操作对象:
  3. 如果操作ID没有指定,会使用[[yiiaseController::defaultAction|default action ID]]默认操作ID;
  4. 如果在[[yiiaseController::actions()|action map]]找到操作ID,会创建一个独立操作;
  5. 如果操作ID对应操作方法,会创建一个内联操作;
  6. 否则会抛出[[yiiaseInvalidRouteException]]异常。
  7. 控制器按顺序调用应用主体、模块(如果控制器属于模块)、控制器的 beforeAction() 方法;
  8. 如果任意一个调用返回false,后面未调用的beforeAction()会跳过并且操作执行会被取消; action execution will be cancelled.
  9. 默认情况下每个 beforeAction() 方法会触发一个 beforeAction 事件,在事件中你可以追加事件处理操作;
  10. 控制器执行操作:
  11. 请求数据解析和填入到操作参数;
  12. 控制器按顺序调用控制器、模块(如果控制器属于模块)、应用主体的 afterAction() 方法;
  13. 默认情况下每个 afterAction() 方法会触发一个 afterAction 事件,在事件中你可以追加事件处理操作;
  14. 应用主体获取操作结果并赋值给响应.