Yii框架2.0的控制器
控制器是继承[[yii\base\Controller]]类的对象,负责处理请求和生成响应。 具体来说,控制器从应用主体接管控制后会分析请求数据并传送到模型, 传送模型结果到视图,最后生成输出响应信息。
控制器是由一个或多个操作来组成的。
控制器的路由由 模型id(仅存在于控制器属于非应用的模块)、 控制器id、 操作id 组成。
路由使用如下格式:
ControllerID/ActionID
如果属于模块下的控制器,使用如下格式:
ModuleID/ControllerID/ActionID
控制器ID:
通常情况下,控制器用来处理请求有关的资源类型,因此控制器ID通常为和资源有关的名词。 例如使用article作为处理文章的控制器ID。
控制器ID应仅包含英文小写字母、数字、下划线、中横杠和正斜杠, 例如 article 和 post-comment 是真是的控制器ID,article?, PostComment, admin\post不是控制器ID。
控制器Id可包含子目录前缀,例如 admin/article 代表 [[yii\base\Application::controllerNamespace|controller namespace]]控制器命名空间下 admin子目录中 article 控制器。 子目录前缀可为英文大小写字母、数字、下划线、正斜杠,其中正斜杠用来区分多级子目录(如 panels/admin)
控制器ID遵循以下规则衍生控制器类名:
将用正斜杠区分的每个单词第一个字母转为大写。注意如果控制器ID包含正斜杠,只将最后的正斜杠后的部分第一个字母转为大写;
去掉中横杠,将正斜杠替换为反斜杠;
增加Controller后缀;
在前面增加[[yii\base\Application::controllerNamespace|controller namespace]]控制器命名空间.
下面为一些示例,假设[[yii\base\Application::controllerNamespace|controller namespace]]控制器命名空间为 app\controllers:
article 对应 app\controllers\ArticleController;
post-comment 对应 app\controllers\PostCommentController; //此种情况为Comment的首字母大写,而它事中间的单词所以用一个中横线标识下。
admin/post-comment 对应 app\controllers\admin\PostCommentController;
adminPanels/post-comment 对应 app\controllers\adminPanels\PostCommentController.
控制器部署
可通过配置 [[yii\base\Application::controllerMap|controller map]] 来强制上述的控制器ID和类名对应, 通常用在使用第三方不能掌控类名的控制器上。
配置 应用配置 中的application configuration web.php,如下所示:
[ 'controllerMap' => [ // 用类名申明 "account" 控制器 'account' => 'app\controllers\UserController', // 用配置数组申明 "article" 控制器 'article' => [ 'class' => 'app\controllers\PostController', 'enableCsrfValidation' => false, ], ], ]
默认控制器 : 框架默认的是 site 控制器,不过可以在 web.php里配置,
[ 'defaultRoute' => 'main', ]
创建操作: 必须以 action开头的函数。操作方法的名字大小写敏感,ActonName 不会被认为事操作方法。
独立操作
独立操作通过继承[[yii\base\Action]]或它的子类来定义。 例如Yii发布的[[yii\web\ViewAction]]和[[yii\web\ErrorAction]]都是独立操作。
要使用独立操作,需要通过控制器中覆盖[[yii\base\Controller::actions()]]方法在action map中申明,如下例所示:
1 public function actions() 2 { 3 return [ 4 // 用类来申明"error" 操作 5 'error' => 'yii\web\ErrorAction', 6 7 // 用配置数组申明 "view" 操作 8 'view' => [ 9 'class' => 'yii\web\ViewAction', 10 'viewPrefix' => '', 11 ], 12 ]; 13 }
如上所示, actions() 方法返回键为操作ID、值为对应操作类名或数组configurations 的数组。 和内联操作不同,独立操作ID可包含任意字符,只要在actions() 方法中申明.
为创建一个独立操作类,需要继承[[yii\base\Action]] 或它的子类,并实现公有的名称为run()的方法, run() 方法的角色和操作方法类似,例如:
namespace app\components; use yii\base\Action; class HelloWorldAction extends Action { public function run() { return "Hello World"; } }
操作参数
内联操作的操作方法和独立操作的 run() 方法可以带参数,称为操作参数。 参数值从请求中获取,对于[[yii\web\Application|Web applications]]网页应用, 每个操作参数的值从$_GET中获得,参数名作为键;
默认操作:
不做处理的话,默认操作就是 index操作,当然也可以修改,直接覆盖父类的 $defaultAction 变量就可以了,例如:
namespace app\controllers; use yii\web\Controller; class SiteController extends Controller { public $defaultAction = 'home'; public function actionHome() { return $this->render('home'); } }
控制器里的createUrl 和 createAbsoluteUrl方法已经删除了,现在使用的`yii\helpers\Url::toRoute` 来代替,也可以用 Yii::$app->getUrlManager()->createUrl($params),实际都是用UrlManager类的createUrl方法来实现的。
控制器生命周期
处理一个请求时,应用主体 会根据请求路由创建一个控制器,控制器经过以下生命周期来完成请求:
- 在控制器创建和配置后,[[yii\base\Controller::init()]] 方法会被调用。
- 控制器根据请求操作ID创建一个操作对象:
- 如果操作ID没有指定,会使用[[yii\base\Controller::defaultAction|default action ID]]默认操作ID;
- 如果在[[yii\base\Controller::actions()|action map]]找到操作ID,会创建一个独立操作;
- 如果操作ID对应操作方法,会创建一个内联操作;
- 否则会抛出[[yii\base\InvalidRouteException]]异常。
- 控制器按顺序调用应用主体、模块(如果控制器属于模块)、控制器的 beforeAction() 方法;
- 如果任意一个调用返回false,后面未调用的beforeAction()会跳过并且操作执行会被取消; action execution will be cancelled.
- 默认情况下每个 beforeAction() 方法会触发一个 beforeAction 事件,在事件中你可以追加事件处理操作;
- 控制器执行操作:
- 请求数据解析和填入到操作参数;
- 控制器按顺序调用控制器、模块(如果控制器属于模块)、应用主体的 afterAction() 方法;
- 默认情况下每个 afterAction() 方法会触发一个 afterAction 事件,在事件中你可以追加事件处理操作;
- 应用主体获取操作结果并赋值给响应.