PHP 小巧简单带静态缓存的模版类
时间:2013-05-03
来源:互联网
class Template { public $caching = false; //模版缓存开关 true | false private $_config = array( 'path' => 'template', //模版文件路径 'compile_path' => 'template_compile', //模版编译文件路径 'suffix' => '.html', //模版后缀 'cache_path' => 'cache', //缓存路径 'cache_name' => '' //缓存名称 ); private $_templateName; private $_templateVars; private static $_instance; private function __construct(){} public static function getInstance() { if (empty(self::$_instance)) { self::$_instance = new self; } return self::$_instance; } public function setConfig($config) { if (!empty($config)) { $config = array_merge($this->_config, $config); } $this->_config = array_change_key_case($config); return $this; } /* * 模版变量赋值 * @param mixed 变量名称 支持批量设置,如: array('title' => '', 'name' => ''); * @param mixed 变量值 如果为批量设置方式则无效 */ public function assign($vars, $value = '') { if (is_array($vars)) { foreach ($vars as $key => $val) { if (!empty($key)) $this->_templateVars[$key] = $val; } } else { if (!empty($vars)) $this->_templateVars[$vars] = $value; } } private function _templatePath($templateName) { return $this->_config['path'].'/'.$templateName.$this->_config['suffix']; } private function _compilePath($templateName) { return $this->_config['compile_path'].'/'.$templateName.'.compile'; } //使用__var__这样的命名尽量避免污染模版变量 public function fetch($__templateName__) { $this->_compile($__templateName__); if (!empty($this->_templateVars)) extract($this->_templateVars); ob_start(); $__file__ = $this->_compilePath($__templateName__); if (is_file($__file__)) { include $this->_compilePath($__templateName__); $content = ob_get_clean(); return $content; } else { throw new Exception(__METHOD__.'找不到模板编译文件: '.$__file__); } } private function _compile($templateName) { $templateFile = $this->_templatePath($templateName); $compileFile = $this->_compilePath($templateName); if (!is_file($compileFile) || @filemtime($templateFile) > @filemtime($compileFile)) { if (is_file($templateFile)) { $content = file_get_contents($templateFile); $content = self::_parse($content); self::_makeDir(dirname($compileFile)); file_put_contents($compileFile, $content); } else { echo '模板文件不存在: '.$templateFile; throw new Exception(__METHOD__.'找不到模板文件: '.$templateFile); } } } private static function _parse($content) { //过滤模板<!-- -->注释 $content = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s", "{\\1}", $content); //模板包含模板 $content = preg_replace("/\{template\sfile=(\"?)([\w|-]+)\\1\}/i", "<?php echo \$this->fetch('\\2'); ?>", $content); //PHP标签 $content = preg_replace("/\{php\s+(.+)\}/", "<?php \\1?>", $content); //echo变量 $content = preg_replace("/\{(\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/", "<?php echo \\1;?>", $content); //echo常量 $content = preg_replace("/\{([A-Z_\x7f-\xff][A-Z0-9_\x7f-\xff]*)\}/s", "<?php echo \\1;?>", $content); //echo函数 $content = preg_replace("/\{([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff:]*\(([^{}]*)\))\}/","<?php echo \\1;?>", $content); //if $content = preg_replace("/\{if\s+(.+?)\}/", "<?php if(\\1) { ?>", $content); //else $content = preg_replace("/\{else\}/", "<?php } else { ?>", $content); //elseif $content = preg_replace("/\{elseif\s+(.+?)\}/", "<?php } elseif (\\1) { ?>", $content); //end if $content = preg_replace("/\{\/if\}/", "<?php } ?>", $content); //foreach $content = preg_replace("/\{loop\s+(\S+)\s+(\S+)\}/", "<?php if(is_array(\\1)) foreach(\\1 AS \\2) { ?>", $content); $content = preg_replace("/\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}/","<?php if(is_array(\\1)) foreach(\\1 AS \\2 => \\3) { ?>", $content); $content = preg_replace("/\{\/loop\}/", "<?php } ?>", $content); //echo foreach 变量 $content = preg_replace("/\{(\\$[a-zA-Z0-9_\[\]\'\"\$\x7f-\xff]+)\}/es", "self::_quote('<?php echo \\1;?>')", $content); return $content; } private static function _quote($var) { return str_replace("\\\"", "\"", preg_replace("/\[([a-zA-Z0-9_\-\.\x7f-\xff]+)\]/s", "['\\1']", $var)); } /* * 模版输出 * @param string 如果之前有缓存isCache(template)判断,可留空 */ public function display($templateName = '') { if (!empty($this->_templateName)) $templateName = $this->_templateName; if ($this->caching == true) { $templateFile = $this->_templatePath($templateName); $cacheFile = $this->_getCacheFile(); if (!$this->_checkCache($templateFile, $cacheFile)) { $content = $this->fetch($templateName); self::_makeDir(dirname($cacheFile)); file_put_contents($cacheFile, $content); } else { $content = file_get_contents($cacheFile); } echo $content; } else { echo $this->fetch($templateName); } } private function _getCacheFile() { if (!$this->_config['cache_name']) $this->_config['cache_name'] = $this->_templateName; return $this->_config['cache_path'].'/'.$this->_config['cache_name'].'.html'; } private static function _checkCache($templateFile, $cacheFile) { if (!is_file($cacheFile) || @filemtime($templateFile) > @filemtime($cacheFile)) { return false; } return true; } public function isCache($templateName) { $this->_templateName = $templateName; if ($this->caching == false) return false; $templateFile = $this->_templatePath($templateName); $cacheFile = $this->_getCacheFile(); if (!$this->_checkCache($templateFile, $cacheFile)) return false; return true; } /* * 清除模版HTML缓存文件 * @param string 参数同glob 默认为当前模版 * [url=http://bbs.phpchina.com/home.php?mod=space&uid=987628]@Return[/url] bool */ public function clearCache($search = '') { if (!empty($search)) { $files = glob($this->_config['cache_path'].'/'.$search.'.html'); if (!empty($files)) { foreach ($files as $file) { if (is_file($file)) unlink($file); } return true; } } return is_file($this->_getCacheFile()) ? unlink($this->_getCacheFile()) : false; } private static function _makeDir($dir, $mode = 0777) { if (!is_dir($dir)) { self::_makeDir(dirname($dir), $mode); return mkdir($dir, $mode); } return true; } } $Tpl = Template::getInstance(); $Tpl->setConfig(array('path' => 'tpl')); $Tpl->setConfig(array('compile_path' => 'tpl_c')); $Tpl->setConfig(array('cache_path' => 'tpl_cache')); //常规赋值 $Tpl->assign('author', '作者'); //批量赋值 $Tpl->assign(array('title' => '标题', 'content' => '内容')); //使用try来捕获类可能存在的错误 try{ //开启缓存(永久缓存) $Tpl->caching = true; // *注意 caching 必须开启,下面的缓存才有效 $page = 1; //这里表示分页$_GET['page'] //设置缓存文件名 $Tpl->setConfig(array('cache_name' => 'index-'.$page)); //根据分页来缓存 //检查缓存是否存在 if (!$Tpl->isCache('index')) { //这里的index为模版名,下面的display就不用再传递 echo '写缓存...并且一系列的操作……'; } $Tpl->display(); } catch (Exception $e) { echo '<p>'.$e->getMessage().'</p>'; } //清除缓存 //比如在后台操作 //后台可能模板类被重新实例化 (配置前台缓存的目录) $Tpl->setConfig(array('cache_path' => 'tpl_cache')); //参数同php glob()函数 $Tpl->clearCache('index-1'); //清除index-1缓存文件 $Tpl->clearCache('index-*'); //清除index-为前缀的缓存文件
模版语法:http://www.yytweb.com/a/41.html
作者: gyyst 发布时间: 2013-05-03
看着写那么一大堆assign,就相当不爽,浪费太多时间在没有意义的assign上了。远不如php include来得方便
作者: xuer 发布时间: 2013-05-04
xuer 发表于 2013-5-4 23:04
看着写那么一大堆assign,就相当不爽,浪费太多时间在没有意义的assign上了。远不如php include来得方便 ...
看着写那么一大堆assign,就相当不爽,浪费太多时间在没有意义的assign上了。远不如php include来得方便 ...
. 受打击了
作者: gyyst 发布时间: 2013-05-05
嗯还可以简化一下额 呵呵

作者: Frank_Luo 发布时间: 2013-05-14
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28