0

0

MVC的调度器和模板类

PHP中文网

PHP中文网

发布时间:2016-05-25 17:15:09

|

1587人浏览过

|

来源于php中文网

原创

调整了设置参数的的方法

新增了普通路由模式

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();
?>

               

           

网奇.NET网络商城系统
网奇.NET网络商城系统

系统优势: 1、 使用全新ASP.Net+c#和三层结构开发. 2、 可生成各类静态页面(html,htm,shtm,shtml和.aspx) 3、 管理后台风格模板自由选择,界面精美 4、 风格模板每月更新多套,还可按需定制 5、 独具的缓存技术加快网页浏览速度 6、 智能销售统计,图表分析 7、 集成国内各大统计系统 8、 多国语言支持,内置简体繁体和英语 9、 UTF-8编码,可使用于全球

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Golang处理数据库错误教程合集
Golang处理数据库错误教程合集

本专题整合了Golang数据库错误处理方法、技巧、管理策略相关内容,阅读专题下面的文章了解更多详细内容。

2

2026.02.06

java多线程方法汇总
java多线程方法汇总

本专题整合了java多线程面试题、实现函数、执行并发相关内容,阅读专题下面的文章了解更多详细内容。

0

2026.02.06

1688阿里巴巴货源平台入口与批发采购指南
1688阿里巴巴货源平台入口与批发采购指南

本专题整理了1688阿里巴巴批发进货平台的最新入口地址与在线采购指南,帮助用户快速找到官方网站入口,了解如何进行批发采购、货源选择以及厂家直销等功能,提升采购效率与平台使用体验。

90

2026.02.06

快手网页版入口与电脑端使用指南 快手官方短视频观看入口
快手网页版入口与电脑端使用指南 快手官方短视频观看入口

本专题汇总了快手网页版的最新入口地址和电脑版使用方法,详细提供快手官网直接访问链接、网页端操作教程,以及如何无需下载安装直接观看短视频的方式,帮助用户轻松浏览和观看快手短视频内容。

15

2026.02.06

C# 多线程与异步编程
C# 多线程与异步编程

本专题深入讲解 C# 中多线程与异步编程的核心概念与实战技巧,包括线程池管理、Task 类的使用、async/await 异步编程模式、并发控制与线程同步、死锁与竞态条件的解决方案。通过实际项目,帮助开发者掌握 如何在 C# 中构建高并发、低延迟的异步系统,提升应用性能和响应速度。

10

2026.02.06

Python 微服务架构与 FastAPI 框架
Python 微服务架构与 FastAPI 框架

本专题系统讲解 Python 微服务架构设计与 FastAPI 框架应用,涵盖 FastAPI 的快速开发、路由与依赖注入、数据模型验证、API 文档自动生成、OAuth2 与 JWT 身份验证、异步支持、部署与扩展等。通过实际案例,帮助学习者掌握 使用 FastAPI 构建高效、可扩展的微服务应用,提高服务响应速度与系统可维护性。

6

2026.02.06

JavaScript 异步编程与事件驱动架构
JavaScript 异步编程与事件驱动架构

本专题深入讲解 JavaScript 异步编程与事件驱动架构,涵盖 Promise、async/await、事件循环机制、回调函数、任务队列与微任务队列、以及如何设计高效的异步应用架构。通过多个实际示例,帮助开发者掌握 如何处理复杂异步操作,并利用事件驱动设计模式构建高效、响应式应用。

7

2026.02.06

java连接字符串方法汇总
java连接字符串方法汇总

本专题整合了java连接字符串教程合集,阅读专题下面的文章了解更多详细操作。

25

2026.02.05

java中fail含义
java中fail含义

本专题整合了java中fail的含义、作用相关内容,阅读专题下面的文章了解更多详细内容。

28

2026.02.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
ThinkPHP6.x 微实战--十天技能课堂
ThinkPHP6.x 微实战--十天技能课堂

共26课时 | 1.7万人学习

Swoft2.x速学之http api篇课程
Swoft2.x速学之http api篇课程

共16课时 | 1.0万人学习

第二十四期_PHP8编程
第二十四期_PHP8编程

共86课时 | 3.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号