控制器(Controller)由一些类组成,根据预先定义的配置选项处理用户请求。一个典型的用户请求如下:
http://www.myhost.com/mycompany/Main.php?do=salesReport.
php.MVC 控制器由两部分组成:前端控制器和控制器。当请求到来时,前端控制器负责安装应用程序,控制器则根据phpmvc-config.xml的配置属性处理请求。
图6显示了前端控制器的主要任务。
图6
用户请求被Main.php文件接收,这里,将设置一些初始化参数。前端控制器将执行以下任务:
定义应用程序路径:这将指定php.MVC类库以及Web应用程序的路径,如下:
$appServerRootDir = 'C:/WWW/phpmvc-base';
$moduleRootDir = 'C:/WWW/mycompany';
定义应用程序的ActionDispatcher:我们通常需要扩展框架ActionDispatcher来定义自己的Dispatcher类:
$actionDispatcher = 'MyActionDispatcher';
初始化应用程序类路径:为了将类和资源装入,前端控制器将导入预先定义的全局路径以及应用程序路径。我们可以在/WEB-INF/ModulePaths.php中设置路径,如下:
$appDirs = array();
...
$appDirs = 'WEB-INF/report_tpl';
$appDirs = 'WEB-INF/report_classes';
包含应用程序类:前端控制器将导入它所需要的类文件,我们也可以用/WEB-INF/prepend.php文件来有选择性地导入一些特殊的应用程序类文件。如下:
include_once './WEB-INF/mytools/MyTools.php';
配置应用程序:前端控制器将为应用程序设置配置信息,比如我们先前定义的ActionDispatcher。
初始化控制器:前端控制器现在将创建一个应用服务器实例(ActionServer)。
导入配置信息:前端控制器现在将导入应用程序配置信息,假如phpmvc-config.xml从最后一次请求后被修改了,phpmvc-config.xml文件将被重新处理并将数据缓存到/WEB-INF/phpmvc-config.data中。
初始化HTTP请求:前端控制器现在将设置HTTP请求并添加请求属性。
调用应用程序控制器:前端控制器现在已经完成了准备工作,将会把处理权交给控制器。
控制器接收从前端控制器传来的请求,根据配置属性执行一系列操作。
图7描述了php.MVC控制器的任务。
图7
处理action路径:控制器将根据请求路径识别出关键字,选择一个action映射。比如请求路径为:
http://www.myhost.com/mycompany/Main.php?do=salesReport, action路径就为salesReport。
处理现场:根据需要为当前用户选择一个Locale
处理内容格式:根据需要设置内容格式,默认为text/html。
处理不缓存:根据需要设置不缓存头信息,默认为:
"Pragma", "No-cache"
"Cache-Control", "no-cache"
"Expires", 1
处理预处理任务:可以在自定义的ActionServer子类中覆盖这个方法,执行一些指定的预处理任务。
处理Action映射:控制器将根据请求识别action映射,根据phpmvc-config.xml的相应节点生成action映射对象(ActionConfig),比如:<action path = "salesReport" .../>。
处理角色:检查能执行这个action的所有必须的认证。
处理ActionForm:控制器将根据action映射找到相关联的ActionForm,form-bean就是由action的name属性指定,比如:
<action ... name = "salesReportForm" .../>。
处理Populate:根据请求参数设置ActionForm实例的属性。
验证ActionForm:根据action的validate属性值如:<action validate = "true" .../>,决定是否调用ActionForm的validate()方法。如果validate()返回False(验证失败),控制器将用action中input属性所指定的显示资源(模板)显示错误,比如:
<action path = "salesReport"
...
validate = "true"
input = reportsIndex.tpl>
假如validate()返回True(验证通过),则将继续处理。处理Forward:控制器检查forward映射的URI是否正常,如果是,继续处理。
处理Include:控制器检查include映射的URI是否正常,如果是,继续处理。
处理Action创建:控制器将创建或获取Action实例来处理这个请求,这是用action的type属性来定义的,比如:
<action path = "salesReport"
type = "SalesReportAction"
...
处理Action执行:控制器现在将调用Action类的execute()方法,比如SalesReportAction->execute(...)。在该方法内,我们将调用业务处理逻辑类。
处理Action链:控制器将检查是否还有另外一个Action需要处理,在应用程序配置文件中,我们通过ActionChain能定义一系列Action,为了定义ActionChain,需要为action节点的forward元素添加一个nextActionPath属性,比如:
<action path = "salesReport"
type = "SalesReportAction"
...
<forward
name = "salesReportSuccess"
path = "salesReport.tpl"
nextActionPath = "salesReport2"/>
...
forward元素的path属性是必须项,假如这个特殊的Action没有输出,我们可以设置path = ""。
处理Action Forward:控制器将转发或重定向到指定的资源,一个forward请求在当前处理器中被处理。RequestProcessor只是把控制权交给ActionDispatcher,那里包含了指定的URI模板。比如:
<forward
name="forward_path
path="forwardRequest"
redirect="false"/>
重定向请求实际是发送给客户端浏览器一个标头响应,然后重定向到一个新的URL。在发送重定向标头信息时当前的处理将立即终止。
<!-- This server -->
<forward
name="redirect_path
path="/MyApp/Main.php?do=newRequest"
redirect="true"/><!-- This server, or a remote server -->
<forward
name="redirect_path
path="http://www.myhost.com/MyApp/Main.php?do=newRequest"
redirect="true"/>
假如没有其他的Action需要处理,控制器处理结束。