控制器

控制器是 CController 或者其子类的实例. 用户请求应用时,创建控制器。控制器执行请求action,action通常引入必要的模型并提供恰当的视图。最简单的action仅仅是一个控制器类方法,此方法的名字以action开始。

控制器有默认的action。用户请求不能指定哪一个action执行时,将执行默认的action。缺省情况下,默认的action名为index。可以通过设置CController::defaultAction改变默认的action。

下边是最小的控制器类。因此控制器未定义任何action,请求时会抛出异常。

  1. class SiteController extends CController
  2. {
  3. }

1. 路由(Route) ¶

控制器和actions通过ID标识的。控制器ID的格式: path/to/xyz对应的类文件protected/controllers/path/to/XyzController.php, 相应的 xyz应该用实际的控制器名替换 (例如 post 对应 protected/controllers/PostController.php). Action ID与 action 前辍构成 action method。例如,控制器类包含一个 actionEdit 方法, 对应的 action ID就是 edit

注意: 在1.0.3版本之前, 控制器ID的格式是 path.to.xyz 而不是 path/to/xyz

Users request for a particular controller and action in terms of route. Aroute is formed by concatenating a controller ID and an action ID separatedby a slash. For example, the route post/edit refers to PostControllerand its edit action. And by default, the URLhttp://hostname/index.php?r=post/edit would request for this controllerand action.

注意: By default, routes are case-sensitive. Since version 1.0.1, it is possible to make routes case-insensitive by setting CUrlManager::caseSensitive to be false in the application configuration. When in case-insensitive mode, make sure you follow the convention that directories containing controller class files are in lower case, and both controller map and action map are using keys in lower case.

Since version 1.0.3, an application can contain modules. The route for a controller action inside a module is in the format of moduleID/controllerID/actionID. For more details, see the section about modules.

2. 控制器实例化 ¶

CWebApplication在处理一个新请求时,实例化一个控制器。程序通过控制器的ID,并按如下规则确定控制器类及控制器类所在位置

  • If CWebApplication::catchAllRequest is specified, a controllerwill be created based on this property, and the user-specified controller IDwill be ignored. This is mainly used to put the application undermaintenance mode and display a static notice page.

  • If the ID is found in CWebApplication::controllerMap, thecorresponding controller configuration will be used to create thecontroller instance.

  • If the ID is in the format of 'path/to/xyz', the controller classname is assumed to be XyzController and the corresponding class file isprotected/controllers/path/to/XyzController.php. For example, a controllerID admin/user would be resolved as the controller class UserControllerand the class file protected/controllers/admin/UserController.php.If the class file does not exist, a 404 CHttpException will be raised.

In case when modules are used (available since version 1.0.3), the above process is slighly different. In particular, the application will check if the ID refers to a controller inside a module, and if so, the module instance will be created first followed by the controller instance.

3. Action ¶

As aforementioned, an action can be defined as a method whose name startswith the word action. A more advanced way is to define an action classand ask the controller to instantiate it when requested. This allowsactions to be reused and thus introduces more reusability.

To define a new action class, do the following:

  1. class UpdateAction extends CAction
  2. {
  3. public function run()
  4. {
  5. // place the action logic here
  6. }
  7. }

In order for the controller to be aware of this action, we override theactions() method of our controller class:

  1. class PostController extends CController
  2. {
  3. public function actions()
  4. {
  5. return array(
  6. 'edit'=>'application.controllers.post.UpdateAction',
  7. );
  8. }
  9. }

如上所示,使用路径别名application.controllers.post.UpdateAction 确定action类文件为protected/controllers/post/UpdateAction.php.

Writing class-based actions, we can organize an application in a modularfashion以模块方式组织程序。例如,可以使用下边的目录结构组织控制器代码:

  1. protected/
  2. controllers/
  3. PostController.php
  4. UserController.php
  5. post/
  6. CreateAction.php
  7. ReadAction.php
  8. UpdateAction.php
  9. user/
  10. CreateAction.php
  11. ListAction.php
  12. ProfileAction.php
  13. UpdateAction.php

4. Filter ¶

Filter is a piece of code that is configured to be executed before and/orafter a controller action executes. For example, an access control filtermay be executed to ensure that the user is authenticated before executingthe requested action; a performance filter may be used to measure the timespent in the action execution.

An action can have multiple filters. The filters are executed in the orderthat they appear in the filter list. A filter can prevent the execution ofthe action and the rest of the unexecuted filters.

A filter can be defined as a controller class method. The method name mustbegin with filter. For example, the existence of thefilterAccessControl method defines a filter named accessControl. Thefilter method must be of the signature:

  1. public function filterAccessControl($filterChain)
  2. {
  3. // call $filterChain->run() to continue filtering and action execution
  4. }

where $filterChain is an instance of CFilterChain which represents thefilter list associated with the requested action. Inside the filter method,we can call $filterChain->run() to continue filtering and actionexecution.

A filter can also be an instance of CFilter or its child class. Thefollowing code defines a new filter class:

  1. class PerformanceFilter extends CFilter
  2. {
  3. protected function preFilter($filterChain)
  4. {
  5. // logic being applied before the action is executed
  6. return true; // false if the action should not be executed
  7. }
  8.  
  9. protected function postFilter($filterChain)
  10. {
  11. // logic being applied after the action is executed
  12. }
  13. }

To apply filters to actions, we need to override theCController::filters() method. The method should return an array offilter configurations. For example,

  1. class PostController extends CController
  2. {
  3. ......
  4. public function filters()
  5. {
  6. return array(
  7. 'postOnly + edit, create',
  8. array(
  9. 'application.filters.PerformanceFilter - edit, create',
  10. 'unit'=>'second',
  11. ),
  12. );
  13. }
  14. }

The above code specifies two filters: postOnly and PerformanceFilter.The postOnly filter is method-based (the corresponding filter method isdefined in CController already); while the PerformanceFilter filter isobject-based. The path alias application.filters.PerformanceFilterspecifies that the filter class file isprotected/filters/PerformanceFilter. We use an array to configurePerformanceFilter so that it may be used to initialize the propertyvalues of the filter object. Here the unit property ofPerformanceFilter will be initialized as 'second'.

Using the plus and the minus operators, we can specify which actions thefilter should and should not be applied to. In the above, the postOnlyshould be applied to the edit and create actions, whilePerformanceFilter should be applied to all actions EXCEPT edit andcreate. If neither plus nor minus appears in the filter configuration,the filter will be applied to all actions.

模型

原文: https://www.yiichina.com/doc/guide/1.0/basics.controller