【php源码】Discuz的模板引擎

Discuz的模板引擎 一个较量好的模板引擎类,好久以前就在网上找到,目测这个Discuz的模板引擎应该很老了,是DZ7.2以前的版本了,本身也用得很顺手,分享下这个模板类。
有两个文件。一个模板类,一个模板替换中需要用到的函数

<?php /** * 模板类 - 利用 Discuz 模板引擎理会 * * @package classes * @copyright Copyright (c) 2007-2008 () * @author Akon(番茄红了) <aultoale@gmail.com> * @license PHP Version 3.0 {@link } */ require_once (DIR_ROOT . '/../function/template.func.php'); class Template { const DIR_SEP = DIRECTORY_SEPARATOR; /** * 模板实例 * * @staticvar * @var object Template */ protected static $_instance; /** * 模板参数信息 * * @var array */ protected $_options = array(); /** * 单件模式挪用要领 * * @static * @return object Template */ public static function getInstance() { if (!self :: $_instance instanceof self) self :: $_instance = new self(); return self :: $_instance; } /** * 结构要领 * * @return void */ private function __construct() { $this -> _options = array('template_dir' => 'templates' . self :: DIR_SEP, // 模板文件地址目次 'cache_dir' => 'templates' . self :: DIR_SEP . 'cache' . self :: DIR_SEP, // 缓存文件存放目次 'auto_update' => false, // 当模板文件窜改时是否从头生成缓存 'cache_lifetime' => 0, // 缓存生命周期(分钟),为 0 暗示永久 ); } /** * 设定模板参数信息 * * @param array $options 参数数组 * @return void */ public function setOptions(array $options) { foreach ($options as $name => $value) $this -> set($name, $value); } /** * 设定模板参数 * * @param string $name 参数名称 * @param mixed $value 参数值 * @return void */ public function set($name, $value) { switch ($name) { case 'template_dir': $value = $this -> _trimpath($value); if (!file_exists($value)) $this -> _throwException("未找到指定的模板目次 \"$value\""); $this -> _options['template_dir'] = $value; break; case 'cache_dir': $value = $this -> _trimpath($value); if (!file_exists($value)) $this -> _throwException("未找到指定的缓存目次 \"$value\""); $this -> _options['cache_dir'] = $value; break; case 'auto_update': $this -> _options['auto_update'] = (boolean) $value; break; case 'cache_lifetime': $this -> _options['cache_lifetime'] = (float) $value; break; default: $this -> _throwException("未知的模板设置选项 \"$name\""); } } /** * 通过把戏要领设定模板参数 * * @see Template::set() * @param string $name 参数名称 * @param mixed $value 参数值 * @return void */ public function __set($name, $value) { $this -> set($name, $value); } /** * 获取模板文件 * * @param string $file 模板文件名称 * @return string */ public function getfile($file) { $cachefile = $this -> _getCacheFile($file); if (!file_exists($cachefile)) $this -> cache($file); return $cachefile; } /** * 检测模板文件是否需要更新缓存 * * @param string $file 模板文件名称 * @param string $md5data 模板文件 md5 校验信息 * @param integer $md5data 模板文件到期时间校验信息 * @return void */ public function check($file, $md5data, $expireTime) { if ($this -> _options['auto_update'] && md5_file($this -> _getTplFile($file)) != $md5data) $this -> cache($file); if ($this -> _options['cache_lifetime'] != 0 && (time() - $expireTime >= $this -> _options['cache_lifetime'] * 60)) $this -> cache($file); } /** * 对模板文件举办缓存 * * @param string $file 模板文件名称 * @return void */ public function cache($file) { $tplfile = $this -> _getTplFile($file); if (!is_readable($tplfile)) { $this -> _throwException("模板文件 \"$tplfile\" 未找到可能无法打开"); } // 取得模板内容 $template = file_get_contents($tplfile); // 过滤 <!--{}--> $template = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s", "{\\1}", $template); // 替换语言包变量 // $template = preg_replace("/\{lang\s+(.+?)\}/ies", "languagevar('\\1')", $template); // 替换 PHP 换行符 $template = str_replace("{LF}", "<?=http://enenba.com/\"\\n\"?>", $template); // 替换直接变量输出 $varRegexp = "((\\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)" . "(\[[a-zA-Z0-9_\-\.\"\'\[\]\$\x7f-\xff]+\])*)"; $template = preg_replace("/\{(\\\$[a-zA-Z0-9_\[\]\'\"\$\.\x7f-\xff]+)\}/s", "<?=http://enenba.com/\\1?>", $template); $template = preg_replace("/$varRegexp/es", "addquote('<?=http://enenba.com/\\1?>')", $template); $template = preg_replace("/\<\?\=http://enenba.com/\<\?\=$varRegexp\?\>\?\>/es", "addquote('<?=http://enenba.com/\\1?>')", $template); // 替换模板载入呼吁 $template = preg_replace("/[\n\r\t]*\{template\s+([a-z0-9_]+)\}[\n\r\t]*/is", "\r\n<? include(\$template->getfile('\\1')); ?>\r\n", $template ); $template = preg_replace("/[\n\r\t]*\{template\s+(.+?)\}[\n\r\t]*/is", "\r\n<? include(\$template->getfile(\\1)); ?>\r\n", $template ); // 替换特定函数 $template = preg_replace("/[\n\r\t]*\{eval\s+(.+?)\}[\n\r\t]*/ies", "stripvtags('<? \\1 ?>','')", $template ); $template = preg_replace("/[\n\r\t]*\{echo\s+(.+?)\}[\n\r\t]*/ies", "stripvtags('<? echo \\1; ?>','')", $template ); $template = preg_replace("/([\n\r\t]*)\{elseif\s+(.+?)\}([\n\r\t]*)/ies", "stripvtags('\\1<? } elseif(\\2) { ?>\\3','')", $template ); $template = preg_replace("/([\n\r\t]*)\{else\}([\n\r\t]*)/is", "\\1<? } else { ?>\\2", $template ); // 替换轮回函数及条件判定语句 $nest = 5; for ($i = 0; $i < $nest; $i++) { $template = preg_replace("/[\n\r\t]*\{loop\s+(\S+)\s+(\S+)\}[\n\r]*(.+?)[\n\r]*\{\/loop\}[\n\r\t]*/ies", "stripvtags('<? if(is_array(\\1)) { foreach(\\1 as \\2) { ?>','\\3<? } } ?>')", $template ); $template = preg_replace("/[\n\r\t]*\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}[\n\r\t]*(.+?)[\n\r\t]*\{\/loop\}[\n\r\t]*/ies", "stripvtags('<? if(is_array(\\1)) { foreach(\\1 as \\2 => \\3) { ?>','\\4<? } } ?>')", $template ); $template = preg_replace("/([\n\r\t]*)\{if\s+(.+?)\}([\n\r]*)(.+?)([\n\r]*)\{\/if\}([\n\r\t]*)/ies", "stripvtags('\\1<? if(\\2) { ?>\\3','\\4\\5<? } ?>\\6')", $template ); } // 常量替换 $template = preg_replace("/\{([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/s", "<?=http://enenba.com/\\1?>", $template ); // 删除 PHP 代码断间多余的空格及换行 $template = preg_replace("/ \?\>[\n\r]*\<\? /s", " ", $template); // 其他替换 $template = preg_replace("/\"(http)?[\w\.\/:]+\?[^\"]+?&[^\"]+?\"/e", "transamp('\\0')", $template ); $template = preg_replace("/\<script[^\>]*?src=http://enenba.com/\"(.+?)\".*?\>\s*\<\/script\>/ise", "stripscriptamp('\\1')", $template ); $template = preg_replace("/[\n\r\t]*\{block\s+([a-zA-Z0-9_]+)\}(.+?)\{\/block\}/ies", "stripblock('\\1', '\\2')", $template ); // 添加 md5 及逾期校验 $md5data = md5_file($tplfile); $expireTime = time(); $template = "<? if (!class_exists('template')) die('Access Denied');" . "\$template->getInstance()->check('$file', '$md5data', $expireTime);" . "?>\r\n$template"; // 写入缓存文件 $cachefile = $this -> _getCacheFile($file); $makepath = $this -> _makepath($cachefile); if ($makepath !== true) $this -> _throwException("无法建设缓存目次 \"$makepath\""); file_put_contents($cachefile, $template); } /** * 将路径批改为适合操纵系统的形式 * * @param string $path 路径名称 * @return string */ protected function _trimpath($path) { return str_replace(array('/', '\\', '//', '\\\\'), self :: DIR_SEP, $path); } /** * 获取模板文件名及路径 * * @param string $file 模板文件名称 * @return string */ protected function _getTplFile($file) { return $this -> _trimpath($this -> _options['template_dir'] . self :: DIR_SEP . $file); } /** * 获取模板缓存文件名及路径 * * @param string $file 模板文件名称 * @return string */ protected function _getCacheFile($file) { $file = preg_replace('/\.[a-z0-9\-_]+$/i', '.cache.php', $file); return $this -> _trimpath($this -> _options['cache_dir'] . self :: DIR_SEP . $file); } /** * 按照指定的路径建设不存在的文件夹 * * @param string $path 路径/文件夹名称 * @return string */ protected function _makepath($path) { $dirs = explode(self :: DIR_SEP, dirname($this -> _trimpath($path))); $tmp = ''; foreach ($dirs as $dir) { $tmp .= $dir . self :: DIR_SEP; if (!file_exists($tmp) && !@mkdir($tmp, 0777)) return $tmp; } return true; } /** * 抛出一个错误信息 * * @param string $message * @return void */ protected function _throwException($message) { throw new Exception($message); } } ?>

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/7822.html