日期:2014-05-17 浏览次数:20454 次
为了能更清晰地了解应用控制器总体实现的结构,代码中需要使用到的类都已经在之前实现了,现在只剩下的是核心的部分: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