浩天 发表于 2019-12-25 08:36:10

discuz模板解析注释

<?php

function parse_template($tplfile, $objfile) {
global $options;

//循环嵌套次数
$nest = 3;

//打开模板文件
if(!$fp = fopen($tplfile, ‘rb’)) {
exit(’Current template file not found or have no access!’);
}

$template = fread($fp, filesize($tplfile));
fclose($fp);

//匹配变量
//双引号(单引号)内的\具有转义所以,要得到一个必须写为\\;要得到一个$必须写为\$;最后结果为\$,可在正则中使用的变量符号
$var_regexp = “((\\\$*)(\[\$\x7f-\xff]+\])*)”;

//匹配字符
$const_regexp = “(*)”;

//清除缩进(tab)
$template = preg_replace(”/([\n\r]+)\t+/s”, “\1“, $template);

//清除注释(<!– –>),方便后续操作,不需要匹配多余的<!–
$template = preg_replace(”/\<\!\-\-\{(.+?)\}\-\-\>/s”, “{\\1}”, $template);

//将{LF}替换成一个硬回车(\n)
$template = str_replace(”{LF}”, “<?=\”\
\“?>”, $template);

//匹配多种变量形式,包括$xxx[”xxxx”]与$xxx[$xxx]、或$xxx
$template = preg_replace(”/\{(\\\$\’”$\.\x7f-\xff]+)\}/s”, “<?=\\1?>”, $template);

//使用/e修正符,可使替换元素以php代码执行后,再进行replace.
$template = preg_replace(”/$var_regexp/es”, “addquote(’<?=\\1?>’)”, $template);

//再次替换叠加字符串变量
$template = preg_replace(”/\<\?\=\<\?\=$var_regexp\?\>\?\>/es”, “addquote(’<?=\\1?>’)”, $template);

//子模板嵌套解析
$template = preg_replace(”/[\n\r\t]*\{template\s+(+)\}[\n\r\t]*/is”, “
<? include template(’\1′); ?>\n”, $template);
$template = preg_replace(”/[\n\r\t]*\{template\s+(.+?)\}[\n\r\t]*/is”, “
<? include template(\\1); ?>\n”, $template);

//eval语法解析
$template = preg_replace(”/[\n\r\t]*\{eval\s+(.+?)\}[\n\r\t]*/ies”, “stripvtags(’
<? \\1; ?>\n’,”)”, $template);

//echo语法解析
$template = preg_replace(”/[\n\r\t]*\{echo\s+(.+?)\}[\n\r\t]*/ies”, “stripvtags(’
<? echo \\1; ?>\n’,”)”, $template);

//elseif语法解析
$template = preg_replace(”/[\n\r\t]*\{elseif\s+(.+?)\}[\n\r\t]*/ies”, “stripvtags(’
<? } elseif(\\1) { ?>\n’,”)”, $template);

//else语法解析
$template = preg_replace(”/[\n\r\t]*\{else\}[\n\r\t]*/is”, “
<? } else { ?>\n”, $template);

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) { ?>’,'\n\\3\n<? } } ?>\n’)”, $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) { ?>’,'\n\\4\n<? } } ?>\n’)”, $template);
$template = preg_replace(”/[\n\r\t]*\{if\s+(.+?)\}[\n\r]*(.+?)[\n\r]*\{\/if\}[\n\r\t]*/ies”, “stripvtags(’
<? if(\\1) { ?>’,'\n\\2\n<? } ?>\n’)”, $template);
}

//常量直接输出..
$template = preg_replace(”/\{$const_regexp\}/s”, “<?=\\1?>”, $template);

//相临定界符清除(使语法更加连贯)
$template = preg_replace(”/ \?\>[\n\r]*\<\? /s”, ” “, $template);

if(!@$fp = fopen($objfile, ‘wb’)) {
exit(’Directory \’./cache/template/\’ not found or have no access!’);
}

//转换链接中的&符号为&使编译模板读取时能够正常不会将其视为引用..
$template = preg_replace(”/\”(http)?[\w\.\/:]+\?[^\”]+?&[^\”]+?\”/e”, “transamp(’\′)”, $template);

flock($fp, 2);
fwrite($fp, $template);
fclose($fp);
}

//转换&避免&以引用方式执行..
function transamp($str) {
$str = str_replace(’&’, ‘&’, $str);
$str = str_replace(’&’, ‘&’, $str);
$str = str_replace(’”‘, ‘”‘, $str);
return $str;
}

//将$var字符串,转换为可执行的php代码形式,并返回其结果..
//\”转换为”,将为转换为[’xxx’]
function addquote($var) {
return str_replace(”\\”", “”", preg_replace(”/\[(+)\]/s”, “[’\1′]”, $var));
}

//设置语言变量
function languagevar($var) {
return $GLOBALS[’language’][$var] ? $GLOBALS[’language’][$var] : “!$var!”;
}
//清理或转换标签为php语法
function stripvtags($expr, $statement) {
$expr = str_replace(”\\”", “”", preg_replace(”/\<\?\=(\\\$.+?)\?\>/s”, “\1“, $expr));
$statement = str_replace(”\\”", “”", $statement);
return $expr.$statement;
}

?>

页: [1]
查看完整版本: discuz模板解析注释