Files
yii/docs/guide/zh_cn/basics.controller.txt
2009-04-05 21:36:33 +00:00

219 lines
8.0 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
控制器
==========
控制器是 [CController] 或者其子类的实例. 用户请求应用时,创建控制器。
控制器执行请求actionaction通常引入必要的模型并提供恰当的视图。
最简单的`action`仅仅是一个控制器类方法,此方法的名字以`action`开始。
控制器有默认的action。用户请求不能指定哪一个action执行时将执行默认的action。
缺省情况下,默认的action名为`index`。可以通过设置[CController::defaultAction]改变默认的action。
下边是最小的控制器类。因此控制器未定义任何action,请求时会抛出异常。
~~~
[php]
class SiteController extends CController
{
}
~~~
路由(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`。
> Note|注意: 在1.0.3版本之前, 控制器ID的格式是 `path.to.xyz` 而不是 `path/to/xyz`。
Users request for a particular controller and action in terms of route. A
route is formed by concatenating a controller ID and an action ID separated
by a slash. For example, the route `post/edit` refers to `PostController`
and its `edit` action. And by default, the URL
`http://hostname/index.php?r=post/edit` would request for this controller
and action.
> Note|注意: 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|CWebApplication::controllerMap]
>and [action map|CController::actions] are using keys in lower case.
Since version 1.0.3, an application can contain [modules](/doc/guide/basics.module). 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](/doc/guide/basics.module).
控制器实例化
------------------------
[CWebApplication]在处理一个新请求时实例化一个控制器。程序通过控制器的ID并按如下规则确定控制器类及控制器类所在位置
- If [CWebApplication::catchAllRequest] is specified, a controller
will be created based on this property, and the user-specified controller ID
will be ignored. This is mainly used to put the application under
maintenance mode and display a static notice page.
- If the ID is found in [CWebApplication::controllerMap], the
corresponding controller configuration will be used to create the
controller instance.
- If the ID is in the format of `'path/to/xyz'`, the controller class
name is assumed to be `XyzController` and the corresponding class file is
`protected/controllers/path/to/XyzController.php`. For example, a controller
ID `admin/user` would be resolved as the controller class `UserController`
and 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](/doc/guide/basics.module) 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.
Action
------
As aforementioned, an action can be defined as a method whose name starts
with the word `action`. A more advanced way is to define an action class
and ask the controller to instantiate it when requested. This allows
actions to be reused and thus introduces more reusability.
To define a new action class, do the following:
~~~
[php]
class UpdateAction extends CAction
{
public function run()
{
// place the action logic here
}
}
~~~
In order for the controller to be aware of this action, we override the
[actions()|CController::actions] method of our controller class:
~~~
[php]
class PostController extends CController
{
public function actions()
{
return array(
'edit'=>'application.controllers.post.UpdateAction',
);
}
}
~~~
如上所示,使用路径别名`application.controllers.post.UpdateAction` 确定action类文件为`protected/controllers/post/UpdateAction.php`.
Writing class-based actions, we can organize an application in a modular
fashion以模块方式组织程序。例如可以使用下边的目录结构组织控制器代码:
~~~
protected/
controllers/
PostController.php
UserController.php
post/
CreateAction.php
ReadAction.php
UpdateAction.php
user/
CreateAction.php
ListAction.php
ProfileAction.php
UpdateAction.php
~~~
Filter
------
Filter is a piece of code that is configured to be executed before and/or
after a controller action executes. For example, an access control filter
may be executed to ensure that the user is authenticated before executing
the requested action; a performance filter may be used to measure the time
spent in the action execution.
An action can have multiple filters. The filters are executed in the order
that they appear in the filter list. A filter can prevent the execution of
the action and the rest of the unexecuted filters.
A filter can be defined as a controller class method. The method name must
begin with `filter`. For example, the existence of the
`filterAccessControl` method defines a filter named `accessControl`. The
filter method must be of the signature:
~~~
[php]
public function filterAccessControl($filterChain)
{
// call $filterChain->run() to continue filtering and action execution
}
~~~
where `$filterChain` is an instance of [CFilterChain] which represents the
filter list associated with the requested action. Inside the filter method,
we can call `$filterChain->run()` to continue filtering and action
execution.
A filter can also be an instance of [CFilter] or its child class. The
following code defines a new filter class:
~~~
[php]
class PerformanceFilter extends CFilter
{
protected function preFilter($filterChain)
{
// logic being applied before the action is executed
return true; // false if the action should not be executed
}
protected function postFilter($filterChain)
{
// logic being applied after the action is executed
}
}
~~~
To apply filters to actions, we need to override the
`CController::filters()` method. The method should return an array of
filter configurations. For example,
~~~
[php]
class PostController extends CController
{
......
public function filters()
{
return array(
'postOnly + edit, create',
array(
'application.filters.PerformanceFilter - edit, create',
'unit'=>'second',
),
);
}
}
~~~
The above code specifies two filters: `postOnly` and `PerformanceFilter`.
The `postOnly` filter is method-based (the corresponding filter method is
defined in [CController] already); while the `PerformanceFilter` filter is
object-based. The path alias `application.filters.PerformanceFilter`
specifies that the filter class file is
`protected/filters/PerformanceFilter`. We use an array to configure
`PerformanceFilter` so that it may be used to initialize the property
values of the filter object. Here the `unit` property of
`PerformanceFilter` will be initialized as `'second'`.
Using the plus and the minus operators, we can specify which actions the
filter should and should not be applied to. In the above, the `postOnly`
should be applied to the `edit` and `create` actions, while
`PerformanceFilter` should be applied to all actions EXCEPT `edit` and
`create`. If neither plus nor minus appears in the filter configuration,
the filter will be applied to all actions.
<div class="revision">$Id: basics.controller.txt 745 2009-02-25 21:45:42Z qiang.xue $</div>