表现层
前端控制器
前端控制器模式用一个中心来处理所有到来的请求,最后调用视图来将结果呈现给用户。
实现
前端控制器模式定义了一个中心入口,每个请求都要从这个入口进入系统。前端控制器处理请求并选择要执行的操作。
<?php
namespace woo\controller;
//...
class Controller
{
private $applicationHelper;
private function __construct()
{
}
static function run()
{
$instance = new Controller();
$instance->init();
$instance->handleRequest();
}
function init()
{
$applicationHelper
= ApplicationHelper::instance();
$applicationHelper->init();
}
function handleRequest()
{
$request = new \woo\controller\Request();
$cmd_r = new \woo\command\CommandResolver();
$cmd = $cmd_r->getCommand($request);
$cmd->execute($request);
}
}
class ApplicationHelper
{
private static $instance;
private $config = "/tmp/data/woo_options.xml";
private function __construct()
{
}
static function instance()
{
if (!self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
function init()
{
$dsn = \woo\base\ApplicationRegistry::getDSN();
if (!is_null($dsn)) {
return;
}
$this->getOptions();
}
private function getOptions()
{
$this->ensure(file_exists($this->config),
"Could not find options file");
$options = SimpleXml_load_file($this->config);
print get_class($options);
$dsn = (string)$options->dsn;
$this->ensure($dsn, "No DSN found");
\woo\base\ApplicationRegistry::setDSN($dsn);
// set other values
}
private function ensure($expr, $message)
{
if (!$expr) {
throw new \woo\base\AppException($message);
}
}
}
class Request
{
private $properties;
private $feedback = array();
function __construct()
{
$this->init();
\woo\base\RequestRegistry::setRequest($this);
}
function init()
{
if (isset($_SERVER['REQUEST_METHOD'])) {
$this->properties = $_REQUEST;
return;
}
foreach ($_SERVER['argv'] as $arg) {
if (strpos($arg, '=')) {
list($key, $val) = explode("=", $arg);
$this->setProperty($key, $val);
}
}
}
function getProperty($key)
{
if (isset($this->properties[$key])) {
return $this->properties[$key];
}
}
function setProperty($key, $val)
{
$this->properties[$key] = $val;
}
function addFeedback($msg)
{
array_push($this->feedback, $msg);
}
function getFeedback()
{
return $this->feedback;
}
function getFeedbackString($separator = "\n")
{
return implode($separator, $this->feedback);
}
}
namespace woo\command;
abstract class Command
{
final function __construct()
{
}
function execute(\woo\controller\Request $request)
{
$this->doExecute($request);
}
abstract function doExecute(\woo\controller\Request $request);
}
class DefaultCommand extends Command
{
function doExecute(\woo\controller\Request $request)
{
$request->addFeedback("Welcome to WOO");
include("woo/view/main.php");
}
}
class CommandResolver
{
private static $base_cmd;
private static $default_cmd;
function __construct()
{
if (!self::$base_cmd) {
self::$base_cmd = new \ReflectionClass("\woo\command\Command");
self::$default_cmd = new DefaultCommand();
}
}
function getCommand(\woo\controller\Request $request)
{
$cmd = $request->getProperty('cmd');
$sep = DIRECTORY_SEPARATOR;
if (!$cmd) {
return self::$default_cmd;
}
$cmd = str_replace(array('.', $sep), "", $cmd);
$filepath = "woo{$sep}command{$sep}{$cmd}.php";
$classname = "woo\\command\\{$cmd}";
if (file_exists($filepath)) {
@require_once("$filepath");
if (class_exists($classname)) {
$cmd_class = new ReflectionClass($classname);
if ($cmd_class->isSubClassOf(self::$base_cmd)) {
return $cmd_class->newInstance();
} else {
$request->addFeedback("command '$cmd' is not a Command");
}
}
}
$request->addFeedback("command '$cmd' not found");
return clone self::$default_cmd;
}
}
\woo\controller\Controller::run();
?>
系统中的控制器复制分配任务给其他。其他类完成了绝大部分实际工作。
ApplicationHelper类并不是前端控制器的核心,但前端控制器通常都需要通过应用助手类来获取基本的配置数据。
前端控制器通常通过运行一个Command对象来调用应用程序逻辑。Command对象通常根据请求中的参数或URL的结构来决定选择哪一个命令。
如果你对项目需要很快完成,或者项目太小以至于前端控制器在系统中的比重太大,那么使用前端控制器就不太合适了。