admin 管理员组

文章数量: 1184232


2024年3月10日发(作者:在线转换字体繁体字)

开源PHP开发框架Yii全方位教程(2)控制器CController

控制器是CController或者其子类的实例。控制器在用户请求应用时创建。控制器执行

所请求的action,action通常加载必要的模型并渲染恰当的视图。最简单的action仅仅

是一个控制器类方法,此方法的名字以action开始。

控制器有默认的action。用户请求不能指定哪一个action执行时,将执行默认的action。

缺省情况下,默认的action名为index。可以通过设置CController::defaultAction改变默认

的action。

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

classSiteControllerextendsCController

{

}

复制代码

路由

控制器和actions通过ID进行标识的。控制器ID的格式:path/to/xyz对应的类文件

protected/controllers/path/to/,相应的xyz应该用实际的控制器名替换

(例如post对应protected/controllers/).ActionID与是没有action前缀

的action方法名字。例如,控制器类包含一个actionEdit方法,对应的actionID就是

edit。

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

用户请求一个特定的controller和action用术语即为路由.路由一个controllerID和

一个actionID连结而成,二者中间以斜线分隔.例如,routepost/edit引用的是

PostController和它的editaction.默认情况下,URLhostname/?r=post/edit

将请求此controller和action.

注意:默认地情况下,路由是大小写敏感的.从版本1.0.1开始,可以让其大小写不

敏感,通过在应用配置中设置CUrlManager::caseSensitive为false.当在大小写不敏感

模式下,确保你遵照约定:包含controller类文件的目录是小写的,controllermap和

actionmap都使用小写的keys.

自版本1.0.3,一个应用可以包含模块(module).一个module中的controller的

route格式是moduleID/controllerID/actionID.更多细节,查阅sectionaboutmodules.

控制器实例化

CWebApplication在处理一个新请求时,实例化一个控制器。程序通过控制器的ID,并

按如下规则确定控制器类及控制器类所在位置

若设置了CWebApplication::catchAllRequest,一个基于此属性的controller将被创建,

同时用户指定的controllerID将被忽略.这主要用来将application置于维护模式,并

显示一个静态的提醒页面.若此ID出现在CWebApplication::controllerMap,对应的

controller配置将被用来创建此controller实例.若此ID的格式是'path/to/xyz',

controller类名字被假定为XyzController而相应的类文件是

protected/controllers/path/to/.例如,一个controllerIDadmin/user将被

解析为controller类UserController,class文件是

protected/controllers/admin/.若此class文件不存在,会触发一个404

CHttpException

一旦使用了modules(自版本1.0.3可用),上面的过程有少许不同.特别的,application

将检查此ID是否引用的是一个module中的controller,如果是,此module实例首

先被创建,然后创建controller实例.

Action

如之前所述,一个action可以被定义为一个方法,其名字以单词action开头.一个更高

级的方式是定义一个action类,当它被请求的时候让controller实例化它.这将允许

action可被重用,因此更加具有可重用性.

要定义一个新action类,这样做:

classUpdateActionextendsCAction

{

publicfunctionrun()

{

//placetheactionlogichere

}

}

复制代码

要让controller知道此action的存在,我们重写controller类的actions()方法:

classPostControllerextendsCController

{

publicfunctionactions()

{

returnarray(

'edit'=>'Action',

);

}

}

复制代码

如上所示,使用路径别名Action确定action类文件为

protected/controllers/post/.

编写基于类的(class-based)action,我们可以以模块化的方式组织程序。例如,可以使用

下边的目录结构组织控制器代码:

protected/

controllers/

post/

user/

复制代码

过滤器(Filter)

Filter是一个代码片段,被配置用来在一个控制器的动作执行之前/后执行.例如,an

accesscontrolfilter可被执行以确保在执行请求的action之前已经过验证;一个

performancefilter可被用来衡量此action执行花费的时间.

一个action可有多个以出现在filter列表中的顺序来执行.一个filter可

以阻止当前action及剩余未执行的filter的执行.

一个filter可被定义为一个controller类的方法.此方法的名字必须以filter开始.例

如,方法filterAccessControl的存在定义了一个名为accessControl的filter.此filter方

法必须如下:

publicfunctionfilterAccessControl($filterChain)

{

//call$filterChain->run()tocontinuefilteringandactionexecution

}

复制代码

$filterChain是CFilterChain的一个实例,CFilterChain代表了与被请求的action相关

的filter列表.在此filter方法内部,我们可以调用$filterChain->run()以继续执行其

他过滤器以及action的执行.

一个filter也可以是CFilter或其子类的一个实例.下面的代码定义了一个新的filter

类:

classPerformanceFilterextendsCFilter

{

protectedfunctionpreFilter($filterChain)

{

//logicbeingappliedbeforetheactionisexecuted

returntrue;//falseiftheactionshouldnotbeexecuted

}

protectedfunctionpostFilter($filterChain)

{

//logicbeingappliedaftertheactionisexecuted

}

}

复制代码

要应用filter到action,我们需要重写CController::filters()方法.此方法应当返回一个

filter配置数组.例如,

classPostControllerextendsCController

{

......

publicfunctionfilters()

{

returnarray(

'postOnly+edit,create',

array(

'manceFilter-edit,create',

'unit'=>'second',

),

);

}

}

复制代码

上面的代码指定了两个filter:postOnly和lyfilter是基于方法

的(对应的filter方法已被定义在CController中);而PerformanceFilterfilter是基于

对象的(object-based).路径别名manceFilter指定filter类文件

是protected/filters/PerformanceFilter.我们使用一个数组来配置PerformanceFilter以便它

可被用来初始化此filter对象的属性值.在这里PerformanceFilter的unit属性被将初

始化为'second'.

使用+和-操作符,我么可以指定哪个action此filter应当和不应当被应用.在上面的例

子中,postOnly被应用到edit和createaction,而PerformanceFilter被应用到所有的

actions除了edit和create.若+或-均未出现在filter配置中,此filter将被用到所有

action.


本文标签: 控制器 执行 请求 方法 例如