深入PHP面向对象、模式与实践——企业模式(3)

来源:互联网 发布:网络推广工作安排 编辑:程序博客网 时间:2024/05/21 08:03

表现层


前端控制器

前端控制器模式用一个中心来处理所有到来的请求,最后调用视图来将结果呈现给用户。

实现

前端控制器模式定义了一个中心入口,每个请求都要从这个入口进入系统。前端控制器处理请求并选择要执行的操作。

这里写图片描述

<?phpnamespace 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的结构来决定选择哪一个命令。

如果你对项目需要很快完成,或者项目太小以至于前端控制器在系统中的比重太大,那么使用前端控制器就不太合适了。

1 0
原创粉丝点击