日期:2014-05-17 浏览次数:20584 次
为了能更清晰地了解应用控制器总体实现的结构,代码中需要使用到的类都已经在之前实现了,现在只剩下的是核心的部分:AppController和Controller。
namespace demo\controller;
/**
* Controller
*/
class Controller {
private $appHelper;
// 不能实例化,只能通过Controller::run()的方式来执行
private function __construct() {
}
public static function run() {
$instance = new self();
// 加载配置
$instance->init();
// 处理请求
$instance->handleReuqest();
}
private function init() {
$appHelper = \demo\controller\ApplicationHelper::getInstance();
$appHelper->init();
}
private function handleReuqest() {
$request = new \demo\controller\Request();
$appController = \demo\base\ApplicationRegistry::getInstance()->getAppController();
// 执行完所有Command,有可能存在forward
while ($cmd = $appController->getCommand($request)) {
// var_dump($cmd);
$cmd->execute($request);
// 把当前Command设为已执行过
$request->setLastCommand($cmd);
}
// 获取视图
$view = $appController->getView($request);
// 显示视图
$this->invokeView($view);
/* $cmdReslover = new \demo\command\CommandReslover();
$cmd = $cmdReslover->getCommand($request);
$cmd->execute($request); */
}
private function invokeView($view) {
include("demo/view/{$view}.php");
exit();
}
}
handleRequest()里面的while循环是为了处理<command>中有可能出现的<forward>,<forward>元素的值是对应的Command子类,这些<command>、<forward>、<view>和<status>的关系都已经被映射到ControllerMap中去了。 Controller执行流程:
1)读取xml配置到controllerMap对象;
2)得到$request;
3)由appController解析$request->getProperty('cmd'),返回$cmd;
4)$cmd->execute($request),如果controllerMap中存在cmd对应的$forward,则$request->setProperties('cmd', $forward),跳到3),否则跳到5);
5)由appController->getView($request)取得视图$view;
6)调用视图invokeView($view);
应用控制器AppController:
namespace demo\controller;
/**
* AppController
*/
class AppController {
private static $baseCmd;
private static $defaultCmd;
private $controllerMap;
// 标记已经执行过的Command,防止出现forward循环
private $invoked = array();
public function __construct(\demo\controller\ControllerMap $camp) {
if (!isset(self::$baseCmd)) {
self::$baseCmd = new \ReflectionClass('\demo\command\Command');
self::$defaultCmd = new \demo\command\DefaultCommand();
}
$this->controllerMap = $camp;
}
public function getView(\demo\controller\Request $request) {
$view = $this->getResource($request, 'View');
return $view;
}
public function getForward(\demo\controller\Request $request) {
$forward = $this->getResource($request, 'Forward');
if ($forward) {
// 设置forward为新的请求
$request->setProperties('cmd', $forward);
}
return $forward;
}
/**
* getView、getForward
* @param \demo\controller\Request $request
* @param string $resType
*/
private function getResource(\demo\controller\Request $request, $resType) {
$cmd = $request->getProperty('cmd');
$previous = $request->getLastCommand();
$status = $previous->getStatus();
$status = $status ? $status : 0;
$acquire = "get{$resType}";
// 按指定优先级获取view或forward
$resource = $this->controllerMap->$acquire($cmd, $status);
if (!$resource) {
$resource = $this->controllerMap->$acquire('default', $status);
}
if (!$resource) {
$resource = $this->controllerMap->$acquire($cmd, 0);
}
if (!$resource) {
$resource = $this->controllerMap->$acquire('default', 0);
}
return $resource;
}
public function getCommand(\demo\controller\Request $request) {
$previous = $request->getLastCo