discuz的模板引擎 一个比较好的模板引擎类,很久以前就在网上找到,目测这个discuz的模板引擎应该很老了,是dz7.2以前的版本了,自己也用得很顺手,分享下这个模板类。 有两个文件。一个模板类,一个模板替换中需要用到的函数 原文地址:http://blog.qita.in
- ?/**
- * 模板类 - 使用 Discuz 模板引擎解析
- * http://blog.qita.in
- */
-
- 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("/{langs+(.+?)}/ies", "languagevar('\1')", $template);
- // 替换 PHP 换行符
- $template = str_replace("{LF}", "="\n"?>", $template);
- // 替换直接变量输出
- $varRegexp = "((\$[a-zA-Z_-][a-zA-Z0-9_-]*)"
- . "([[a-zA-Z0-9_-."'[]$-]+])*)";
- $template = preg_replace("/{(\$[a-zA-Z0-9_[]'"$.-]+)}/s", "=\1?>", $template);
- $template = preg_replace("/$varRegexp/es", "addquote('=\1?>')", $template);
- $template = preg_replace("/\?>/es", "addquote('=\1?>')", $template);
- // 替换模板载入命令
- $template = preg_replace("/[
]*{templates+([a-z0-9_]+)}[
]*/is",
- "
include($template->getfile('\1')); ?>
",
- $template
- );
- $template = preg_replace("/[
]*{templates+(.+?)}[
]*/is",
- "
include($template->getfile(\1)); ?>
",
- $template
- );
- // 替换特定函数
- $template = preg_replace("/[
]*{evals+(.+?)}[
]*/ies",
- "stripvtags(' \1 ?>','')",
- $template
- );
- $template = preg_replace("/[
]*{echos+(.+?)}[
]*/ies",
- "stripvtags(' echo \1; ?>','')",
- $template
- );
- $template = preg_replace("/([
]*){elseifs+(.+?)}([
]*)/ies",
- "stripvtags('\1 } elseif(\2) { ?>\3','')",
- $template
- );
- $template = preg_replace("/([
]*){else}([
]*)/is",
- "\1 } else { ?>\2",
- $template
- );
- // 替换循环函数及条件判断语句
- $nest = 5;
- for ($i = 0; $i $template = preg_replace("/[
]*{loops+(S+)s+(S+)}[
]*(.+?)[
]*{/loop}[
]*/ies",
- "stripvtags(' if(is_array(\1)) { foreach(\1 as \2) { ?>','\3 } } ?>')",
- $template
- );
- $template = preg_replace("/[
]*{loops+(S+)s+(S+)s+(S+)}[
]*(.+?)[
]*{/loop}[
]*/ies",
- "stripvtags(' if(is_array(\1)) { foreach(\1 as \2 => \3) { ?>','\4 } } ?>')",
- $template
- );
- $template = preg_replace("/([
]*){ifs+(.+?)}([
]*)(.+?)([
]*){/if}([
]*)/ies",
- "stripvtags('\1 if(\2) { ?>\3','\4\5 } ?>\6')",
- $template
- );
- }
- // 常量替换
- $template = preg_replace("/{([a-zA-Z_-][a-zA-Z0-9_-]*)}/s",
- "=\1?>",
- $template
- );
- // 删除 PHP 代码断间多余的空格及换行
- $template = preg_replace("/ ?>[
]* // 其他替换
- $template = preg_replace("/"(http)?[w./:]+?[^"]+?&[^"]+?"/e",
- "transamp('\0')",
- $template
- );
- $template = preg_replace("/<script>]*?src="(.+?)".*?>s*</script>/ise",<li> "stripscriptamp('\1')",<li> $template<li> );<li> $template = preg_replace("/[
]*{blocks+([a-zA-Z0-9_]+)}(.+?){/block}/ies",<li> "stripblock('\1', '\2')",<li> $template<li> ); <li> // 添加 md5 及过期校验<li> $md5data = md5_file($tplfile);<li> $expireTime = time();<li> $template = "<? if (!class_exists('template')) die('Access Denied');"<li> . "$template->getInstance()->check('$file', '$md5data', $expireTime);"<li> . "?>
$template"; <li> // 写入缓存文件<li> $cachefile = $this -> _getCacheFile($file);<li> $makepath = $this -> _makepath($cachefile);<li> if ($makepath !== true)<li> $this -> _throwException("无法创建缓存目录 "$makepath"");<li> file_put_contents($cachefile, $template);<li> } <li><li> /**<li> * 将路径修正为适合操作系统的形式<li> * <li> * @param string $path 路径名称<li> * @return string <li> */<li> protected function _trimpath($path) {<li> return str_replace(array('/', '\', '//', '\\'), self :: DIR_SEP, $path);<li> } <li><li> /**<li> * 获取模板文件名及路径<li> * <li> * @param string $file 模板文件名称<li> * @return string <li> */<li> protected function _getTplFile($file) {<li> return $this -> _trimpath($this -> _options['template_dir'] . self :: DIR_SEP . $file);<li> } <li><li> /**<li> * 获取模板缓存文件名及路径<li> * <li> * @param string $file 模板文件名称<li> * @return string <li> */<li> protected function _getCacheFile($file) {<li> $file = preg_replace('/.[a-z0-9-_]+$/i', '.cache.php', $file);<li> return $this -> _trimpath($this -> _options['cache_dir'] . self :: DIR_SEP . $file);<li> } <li><li> /**<li> * 根据指定的路径创建不存在的文件夹<li> * <li> * @param string $path 路径/文件夹名称<li> * @return string <li> */<li> protected function _makepath($path) {<li> $dirs = explode(self :: DIR_SEP, dirname($this -> _trimpath($path)));<li> $tmp = '';<li> foreach ($dirs as $dir) {<li> $tmp .= $dir . self :: DIR_SEP;<li> if (!file_exists($tmp) && !@mkdir($tmp, 0777))<li> return $tmp;<li> } <li> return true;<li> } <li><li> /**<li> * 抛出一个错误信息<li> * <li> * @param string $message <li> * @return void <li> */<li> protected function _throwException($message) {<li> throw new Exception($message);<li> } <li>} <li><li>?><li><li></script>
复制代码
- 模板函数文件
-
/**
- * 模板替换中需要用到的函数
- * http://blog.qita.in
- */
-
- function transamp($template) {
- $template = str_replace('&', '&', $template);
- $template = str_replace('&', '&', $template);
- $template = str_replace('"', '"', $template);
- return $template;
- }
-
- function stripvtags($expr, $statement) {
- $expr = str_replace("\"", """, preg_replace("//s", "\1", $expr));
- $statement = str_replace("\"", """, $statement);
- return $expr . $statement;
- }
-
- function addquote($var) {
- return str_replace("\"", """, preg_replace("/[([a-zA-Z0-9_-.-]+)]/s", "['\1']", $var));
- }
-
- function stripscriptamp($s) {
- $s = str_replace('&', '&', $s);
- return "";
- }
-
- function stripblock($var, $s) {
- $s = str_replace('\"', '"', $s);
- $s = preg_replace("//", "{$\1}", $s);
- preg_match_all("//e", $s, $constary);
- $constadd = '';
- $constary[1] = array_unique($constary[1]);
- foreach($constary[1] as $const) {
- $constadd .= '$__' . $const .' = ' . $const . ';';
- }
- $s = preg_replace("//", "{$__\1}", $s);
- $s = str_replace('?>', "
$$var .= $s = str_replace('', "
EOF;
", $s);
- return "
$constadd$$var = ";
- }
- ?>
复制代码
|