Home  >  Article  >  php教程  >  MVC的调度器和模板类

MVC的调度器和模板类

PHP中文网
PHP中文网Original
2016-05-25 17:15:091203browse

调整了设置参数的的方法

新增了普通路由模式

pathinfo模式支持伪静态了

pathinfo现在支持用户自定义路由了  

tVal = array();
}

/**
 * 设置模版文件目录
 * @param string $dir
*/
 public static function setTemplateDir($dir) {
 self::$tDir = $dir;
}

/**
 * 是否实时编译
 * @param bool $real
*/
 public static function setReal($real) {
 self::$real = (bool) $real;
}

/**
 * 临时文件目录
 * @param string $dir
*/
 public static function setTmpDir($dir) {
 if (!file_exists($dir)) {
 if (!mkdir($dir, 0, true))
 die("tmp dir $dir can't to mkdir");
}
 self::$tTmpDir = realpath($dir);
}

/**
 * URL调度器
 * @param Dispatcher $dispatcher
*/
 public static function setU(&$dispatcher) {
 if (is_object($dispatcher) && method_exists($dispatcher, 'U')) {
 self::$uDispatcher = $dispatcher;
}
}

/**
 * 变量赋值
 * @param mixed $name
 * @param mixed $value
*/
 public function assign($name, $value) {
 $this->tVal[$name] = $value;
}

/**
 * 取得模版的变量
 * @param string $name
*/
 public function getVal($name) {
 if (isset($this->tVal[$name])) {
 return $this->tVal[$name];
}else
 return false;
}

/**
 * 将运行好后的内容,保存到一个html文件中
 * @param string $tFile
 * @param string $html
*/
 public function saveHtml($tFile, $html) {
ob_start();
$this->display($tFile);
 $buffer = ob_get_contents();
ob_end_clean();
 file_put_contents($html, $buffer);
}

/**
 * 运行并显示模版内容
 * @param string $tfile
*/
 public function display($tFile) {
 $this->tFile = $this->parseTemplatePath($tFile);
 if (!self::$real) {
 if (!file_exists($this->getTmpFile()))
$this->parse();
 elseif ((filemtime($this->tFile) > filemtime($this->getTmpFile())))
$this->parse();
}else
$this->parse();
 extract($this->tVal, EXTR_OVERWRITE);
 include $this->getTmpFile();
}

/**
 * 编译好后的文件
 * @return string $filepath
*/
 private function getTmpFile() {
 $basename = basename($this->tFile);
 $pos = strrpos($basename, '.');
 $tmp = 'tpl_' . substr($basename, 0, $pos) . '.php';
 return self::$tTmpDir . '/' . $tmp;
}

 private function parse() {
 $this->tContent = file_get_contents($this->tFile);
$this->parseInclude();
$this->parseSection();
$this->parseVal();
$this->parseEval();
 file_put_contents($this->getTmpFile(), $this->tContent);
}

 private function parseInclude() {
 $this->tContent = preg_replace("/{templates+([a-zA-z0-9._]+)}/ies","$this->subtemplate('$1')", $this->tContent);
}

/**
 * 获取只模版
 * @param string $file
*/
 private function subtemplate($file) {
 return file_get_contents($this->parseTemplatePath($file));
}

/**
 * 解析模版路径
 * @param string $file
 * @return string $filepath
*/
 private function parseTemplatePath($tFile) {
$tFile.='.html';
 $tFile = self::$tDir ? self::$tDir . '/' . $tFile : $tFile;
 if (!file_exists($tFile)) {
 die("No template file $tFile");
 } else {
 $tFile = realpath($tFile);
}
 return $tFile;
}

/**
 * 解析变量
*/
 private function parseVal() {
 $this->tContent = preg_replace("/{(\$S+?)}/is","", $this->tContent);
}

/**
 * 解析段落
*/
 private function parseSection() {
//逻辑
 $this->tContent = preg_replace("/{elseifs+(.+?)}/ies","$this->stripvtags('','')", $this->tContent);
 $this->tContent = preg_replace("/{else}/is","", $this->tContent);
 $this->tContent = preg_replace("/{U((.+?))}/ies","$this->parseUrl('$1')", $this->tContent);
//循环
 for ($i = 0; $i < 6; $i++) {
 $this->tContent = preg_replace("/{loops+(S+)s+(S+)}(.+?){/loop}/ies","$this->stripvtags('','\3')", $this->tContent);
 $this->tContent = preg_replace("/{loops+(S+)s+(S+)s+(S+)}(.+?){/loop}/ies","$this->stripvtags(' \3) { ?>','\4')", $this->tContent);
 $this->tContent = preg_replace("/{ifs+(.+?)}(.+?){/if}/ies","$this->stripvtags('','\2')", $this->tContent);
}
}

 private function stripvtags($expr, $statement='') {
 $expr = str_replace("\"",""", preg_replace("//s","\1", $expr));
 $statement = str_replace("\"",""", $statement);
 return $expr . $statement;
}

/**
 * 解析PHP语句
*/
 private function parseEval() {
 $this->tContent = preg_replace("/{evals+(.+?)}/is","", $this->tContent);
}

/**
 * 解析URL
*/
 private function parseUrl($url) {
 if (is_object(self::$uDispatcher)) {
 return self::$uDispatcher->U($url);
 } else {
 return $url;
}
}
}
?>


查找模块目录的位置
 * DEFAULT_MODULE=>默认Module
 * DEFAULT_ACTION=>默认Action
 * DEBUG=>开启调试(true|false)
 * URL_MODEL=>路由模式(0:普通模式,1:pathinfo模式)
 * URL_DELIMITER=>参数分隔符 pathinfo模式使用
 * URL_HTML_SUFFIX=>'文件后缀' pathinfo模式伪静态使用
 * ENTRY_INDEX=>入口文件
 * URL_ROUTER_ON=>开启自定义路由
 * 普通URL模式U(模块名/操作名?参1=值1&参2=值2)
 * 路由模式U(路由名@?参1=值1&参2=值2)
*/
class Dispatcher {

 private static $instance;
 private static $_SGLOBAL; //调度配置
 private static $route = array(); //泛路由

 private function __construct() {
self::initConfig();
}

 public static function getInstance() {
 if (!self::$instance instanceof self) {
 self::$instance = new self();
}
 return self::$instance;
}

 private function __clone() {

}

/**
 * 运行控制器
*/
 public function run() {
 $route = array();
 if (self::$_SGLOBAL['URL_MODEL'] == 1) {
 $route = $this->pathInfoRoute();
 } else {
 $route = $this->generalRoute();
}
 $modulefile = self::$_SGLOBAL['MODULE_PATH'] ."/{$route['module']}.class.php";
 if (file_exists($modulefile)) {
 include $modulefile;
 if (class_exists($route['module'])) {
 $class = new $route['module'];
 if (method_exists($class, $route['action'])) {
 call_user_func(array(&$class, $route['action']));
}else
 die("in {$route['module']} module no this {$route['action']} action");
}else
 die("no this {$route['module']} module");
 }else {
 die("no this {$route['module']} module");
}
 self::$_SGLOBAL['endtime'] = microtime(true);
$this->debugInfo();
}

/**
 * 输出调试信息
*/
 private function debugInfo() {
 if (self::$_SGLOBAL['DEBUG']) {
 $exectime = self::$_SGLOBAL['endtime'] - self::$_SGLOBAL['starttime'];
 $debuginfo = <<
 .dispatcher_debug_table th,.dispatcher_debug_table td{padding:5px;}
 .dispatcher_debug_table th{
 border-top:1px solid red;
 border-left:1px solid red;
background-color:#ccc;
}
 .dispatcher_debug_table td{
 border-top:1px solid red;
 border-left:1px solid red;
 border-right:1px solid red;
}
.dispatcher_debug_table_last td,.dispatcher_debug_table_last th{
 border-bottom:1px solid red;
}
 .dispatcher_debug_table_title{border-right:1px solid red;}


 ";
 $debuginfo.="";
$debuginfo.="
Debug Info
Execute Time$exectime s
Include File HTML; foreach (get_included_files () as $file) { $debuginfo.=$file ."
"; } $debuginfo.="
Server Info"; $debuginfo.="Host:". $_SERVER['HTTP_HOST'] ."
"; $debuginfo.="PHP_Version:". PHP_VERSION ."
"; $debuginfo.="Server_Version:". $_SERVER['SERVER_SOFTWARE'] ."
"; $debuginfo.="
Client Info"; $debuginfo.="Remote_Addr:". $_SERVER['REMOTE_ADDR'] ."
"; $debuginfo.="User_Agent:". $_SERVER['HTTP_USER_AGENT'] ."
"; $debuginfo.="
"; echo $debuginfo; } } private function generalRoute() { $route = array(); $route['module'] = !empty($_GET['m']) ? $_GET['m'] : self::$_SGLOBAL['DEFAULT_MODULE']; $route['action'] = !empty($_GET['a']) ? $_GET['a'] : self::$_SGLOBAL['DEFAULT_ACTION']; $route['module'].='Action'; unset($_GET['m']); unset($_GET['a']); return $route; } /** * PATHINFO形式的路由调度 * 支持伪静态 */ private function pathInfoRoute() { $route = array(); //伪静态 if (self::$_SGLOBAL['URL_HTML_SUFFIX']) { $pos = strlen($_SERVER['PATH_INFO']) - strlen(self::$_SGLOBAL['URL_HTML_SUFFIX']); $_SERVER['PATH_INFO'] = substr($_SERVER['PATH_INFO'], 0, $pos); } if (!$_SERVER['PATH_INFO'] || $_SERVER['PATH_INFO'] == '/') { $route = array('module' => self::$_SGLOBAL['DEFAULT_MODULE'], 'action' => self::$_SGLOBAL['DEFAULT_ACTION']); } else { $_SERVER['PATH_INFO'] = substr($_SERVER['PATH_INFO'], 1); $pathinfo = explode(self::$_SGLOBAL['URL_DELIMITER'], $_SERVER['PATH_INFO']); //用户自定义路由 if (self::$_SGLOBAL['URL_ROUTER_ON'] && in_array($pathinfo[0], array_keys(self::$route))) { $route['module'] = self::$route[$pathinfo[0]][0]; $route['action'] = self::$route[$pathinfo[0]][1]; $c = explode(',', self::$route[$pathinfo[0]][2]); array_shift($pathinfo); foreach ($c as $r) { $_GET[$r] = array_shift($pathinfo); } } else { if (count($pathinfo) < 2) { $route['module'] = $pathinfo[0] . self::$_SGLOBAL['MODULE_SUFFIX']; $route['action'] = self::$_SGLOBAL['DEFAULT_ACTION'] . self::$_SGLOBAL['ACTION_SUFFIX']; } else { $route['module'] = array_shift($pathinfo) . self::$_SGLOBAL['MODULE_SUFFIX']; $route['action'] = array_shift($pathinfo) . self::$_SGLOBAL['ACTION_SUFFIX']; } } if (count($pathinfo) >= 2) { for ($i = 0, $cnt = count($pathinfo); $i < $cnt; $i++) { if (isset($pathinfo[$i + 1])) { $_GET[$pathinfo[$i]] = $pathinfo[++$i]; } } } } $route['module'].='Action'; $_REQUEST = array_merge($_GET, $_POST); return $route; } /** * url地址组合 * 格式为:Module/Action?get=par(模块名/动作名?get参数) * @param string $url * @return string $url */ public static function U($url) { $pathinfo = parse_url($url); $path = ''; $get = array(); $inroute = false; //用户定义的路由 if (isset($pathinfo['query'])) { $query = explode('&', $pathinfo['query']); foreach ($query as $q) { list($k, $v) = explode('=', $q); $get[$k] = $v; } } if (!self::$_SGLOBAL) { self::initConfig(); } //pathinfo方式的url if (self::$_SGLOBAL['URL_MODEL'] == 1) { if (self::$_SGLOBAL['URL_ROUTER_ON'] && strpos($pathinfo['path'], '@') !== false) { //取出所有用户定义的路由 $routeNames = array_keys(self::$route); $p = substr($pathinfo['path'], 0, -1); if (in_array($p, $routeNames)) { $inroute = true; $path.='/' . $p; $c = explode(',', self::$route[$p][2]); foreach ($c as $v) { if (isset($get[$v])) { $path.=self::$_SGLOBAL['URL_DELIMITER'] . $get[$v]; unset($get[$v]); } } } } if (!$inroute) { if (isset($pathinfo['path'])) { list($module, $action) = explode('/', $pathinfo['path']); $module = $module ? $module : self::$_SGLOBAL['DEFAULT_MODULE']; $action = $action ? $action : self::$_SGLOBAL['DEFAULT_ACTION']; } else { $module = self::$_SGLOBAL['DEFAULT_MODULE']; $action = self::$_SGLOBAL['DEFAULT_ACTION']; } $path ="/$module". self::$_SGLOBAL['URL_DELIMITER'] . $action; } if (!empty($get)) { foreach ($get as $k => $v) { $path.=self::$_SGLOBAL['URL_DELIMITER'] . $k . self::$_SGLOBAL['URL_DELIMITER'] . $v; } } //url伪静态 if (self::$_SGLOBAL['URL_HTML_SUFFIX']) { $path.=self::$_SGLOBAL['URL_HTML_SUFFIX']; } } elseif (self::$_SGLOBAL['URL_MODEL'] == 0) { $url = parse_url($url); if (isset($url['path'])) { list($module, $action) = explode('/', $url['path']); $module = $module ? $module : self::$_SGLOBAL['DEFAULT_MODULE']; $action = $action ? $action : self::$_SGLOBAL['DEFAULT_ACTION']; } else { $module = self::$_SGLOBAL['DEFAULT_MODULE']; $action = self::$_SGLOBAL['DEFAULT_ACTION']; } $path.="?m=$module&a=$action"; if ($url['query']) { $path.='&' . $url['query']; } } if (!self::$_SGLOBAL['URL_REWRITE']) $path = '/' . self::$_SGLOBAL['ENTRY_INDEX'] . $path; return $path; } /** * 初始化配置信息 */ private static function initConfig() { if (defined('APP_PATH')) { //默认模块目录 self::$_SGLOBAL['MODULE_PATH'] = APP_PATH . '/action'; } self::$_SGLOBAL['DEFAULT_ACTION'] = 'index'; //默认action self::$_SGLOBAL['DEFAULT_MODULE'] = 'Index'; //默认module //默认url路由模式,1:pathinfo模式,0为普通模式 self::$_SGLOBAL['URL_MODEL'] = 1; self::$_SGLOBAL['URL_DELIMITER'] = '/'; //参数分隔符 self::$_SGLOBAL['ENTRY_INDEX'] = 'index.php'; self::$_SGLOBAL['URL_HTML_SUFFIX'] = null; //url伪静态 self::$_SGLOBAL['URL_REWRITE'] = false; //URL重写 self::$_SGLOBAL['starttime'] = microtime(true); self::$_SGLOBAL['URL_ROUTER_ON'] = false; //是否启用路由功能 self::$_SGLOBAL['DEBUG'] = false; } /** * 设置选项条件,可设置的有 * MODULE_PATH=>查找模块目录的位置 * DEFAULT_MODULE=>默认Module * DEFAULT_ACTION=>默认Action * DEBUG=>开启调试(true|false) * URL_DELIMITER=>参数分隔符 * URL_MODEL=>路由模式(0:普通模式,1:pathinfo模式) * URL_HTML_SUFFIX=>'文件后缀' pathinfo模式伪静态使用 * ENTRY_INDEX=>入口文件 * URL_ROUTER_ON=>开启自定义路由 * @param array $option 选项 */ public function setOption($option) { $o = array('MODULE_PATH', 'DEFAULT_MODULE', 'DEFAULT_ACTION', 'DEBUG', 'URL_DELIMITER', 'URL_MODEL', 'URL_HTML_SUFFIX', 'ENTRY_INDEX', 'URL_REWRITE', 'URL_ROUTER_ON'); foreach ($option as $k => $v) { if (in_array($k, $o)) { self::$_SGLOBAL[$k] = $v; } } } /** * 设置路由 * array('route'=>array('模块名称', '操作名称','参数1,参数2,参数3')) * @param array $route 路由 */ public function setRoute($route) { self::$route = $route; } } ?>


 1,
 'URL_MODEL' => 1,
 'URL_DELIMITER' => '/',
 'DEFAULT_ACTION' => 'home',
 'URL_REWRITE' => 1,
 'URL_ROUTER_ON' => true,
'URL_HTML_SUFFIX'=>'.html');

//自定义泛路由
$router = array('space'=>array('Space', 'index','uid'));

$dispatcher->setOption($option);
$dispatcher->setRoute($router);

Template::setU($dispatcher);
Template::setReal(true);
Template::setTemplateDir('template/default');
Template::setTmpDir('runtime/tpl');
$dispatcher->run();
?>

               


           


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Previous article:很简单的一个socket客户端类Next article:采集 PHP