默默简单的写了一个模板引擎
2018-09-07 13:33
  引擎文件
复制代码 代码如下:<?php 
/** 
*默默基于Discuz的模板引擎开发的OOP类模板引擎,可支持模板缓存并生成hash的md5值。由hash值来判断模板是否被修改,假如被修改则重新生成缓存文件,假如没有被修改,则直接调用缓存文件. 
*版本:1.0.0.1beta测试版 
*/ 
classmmtp{ 
var$left_tags={; 
var$right_tags=}; 
var$tp_suffix=.html; 
var$cache_suffix=.tpl; 
var$tp_dir=./; 
var$cache_dir=./; 
/** 
*允许循环嵌套的次数,默认为5 
* 
*@varunknown_type 
*/ 
var$nest=5; 
/** 
*模板路径 
* 
*@paramunknown_type$tp_dir 
*@returnmmtp 
*/ 
function__setdir($tp_dir){ 
if(file_exists($tp_dir)){ 
$this->tp_dir=$tp_dir; 
}else{ 
$this->error(模板路径不存在); 
} 
} 
/** 
*设置缓存目录 
* 
*@paramunknown_type$cache_dir 
*/ 
function__setcdir($cache_dir){ 
if(file_exists($cache_dir)){ 
$this->cache_dir=$cache_dir; 
}else{ 
$this->error(缓存路径不存在); 
} 
} 
/** 
*输出错误信息 
* 
*@paramunknown_type$msg 
*/ 
functionerror($msg){ 
print<divstyle=\font-size:12px;color:red;\>.$msg.</div>; 
} 
/** 
*解析模板 
* 
*@paramunknown_type$file 
*/ 
functiontp($file){ 
$tp_path=$this->tp_dir.$file.$this->tp_suffix; 
$fp=fopen($tp_path,rb); 
if(!$this->file_test($tp_path,r)&&!$this->match_hash($file)){ 
$template=$this->file_read($tp_path); 
$var_regexp=((\\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)(\[[a-zA-Z0-9_\-\.\\\[\]\$\x7f-\xff]+\])*); 
$const_regexp=([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*); 
$template=preg_replace(/([\n\r]+)\t+/s,\\1,$template); 
$template=preg_replace(/\<\!\-\-\{(.+?)\}\-\-\>/s,{\\1},$template); 
$template=preg_replace(/\{lang\s+(.+?)\}/ies,languagevar(\\1),$template); 
$template=str_replace({LF},<?=\\\n\?>,$template); 
$template=preg_replace(/\{(\\\$[a-zA-Z0-9_\[\]\\\$\.\x7f-\xff]+)\}/s,<?=\\1?>,$template); 
$template=preg_replace(/$var_regexp/es,\$this->addquote(<?=\\1?>),$template); 
$template=preg_replace(/\<\?\=\<\?\=$var_regexp\?\>\?\>/es,\$this->addquote(<?=\\1?>),$template); 
$template=preg_replace(/[\n\r\t]*\{template\s+([a-z0-9_]+)\}[\n\r\t]*/is,\n<?include(.$this->cache_dir.\\1.$this->cache_suffix.);?>\n,$template); 
$template=preg_replace(/[\n\r\t]*\{template\s+(.+?)\}[\n\r\t]*/is,\n<?include(.$this->cache_dir.\\1.$$this->cache_suffix.);?>\n,$template); 
$template=preg_replace(/[\n\r\t]*\{eval\s+(.+?)\}[\n\r\t]*/ies,\$this->stripvtags(\n<?\\1?>\n,),$template); 
$template=preg_replace(/[\n\r\t]*\{echo\s+(.+?)\}[\n\r\t]*/ies,\$this->stripvtags(\n<?echo\\1;?>\n,),$template); 
$template=preg_replace(/[\n\r\t]*\{elseif\s+(.+?)\}[\n\r\t]*/ies,\$this->stripvtags(\n<?}elseif(\\1){?>\n,),$template); 
$template=preg_replace(/[\n\r\t]*\{else\}[\n\r\t]*/is,\n<?}else{?>\n,$template); 
for($i=0;$i<$this->nest;$i++){ 
$template=preg_replace(/[\n\r\t]*\{loop\s+(\S+)\s+(\S+)\}[\n\r]*(.+?)[\n\r]*\{\/loop\}[\n\r\t]*/ies,\$this->stripvtags(\n<?if(is_array(\\1)){foreach(\\1as\\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,\$this->stripvtags(\n<?if(is_array(\\1)){foreach(\\1as\\2=>\\3){?>,\n\\4\n<?}}?>\n),$template); 
$template=preg_replace(/[\n\r\t]*\{if\s+(.+?)\}[\n\r]*(.+?)[\n\r]*\{\/if\}[\n\r\t]*/ies,\$this->stripvtags(\n<?if(\\1){?>,\n\\2\n<?}?>\n),$template); 
} 
$template=preg_replace(/\{$const_regexp\}/s,<?=\\1?>,$template); 
$template=preg_replace(/\?\>[\n\r]*\<\?/s,,$template); 
$hash=$this->file_hash($tp_path); 
$head_hash=<!--hash=.$hash.-->; 
$foot_time=<!--time=.(date(Y-m-dG:i:s)).-->; 
$this->file_write($this->cache_dir.$file..tpl,$head_hash.$template.$foot_time); 
} 
} 
/** 
*检查文件是否存在并且有读取权限 
* 
*@paramunknown_type$path 
*/ 
functionfile_test($path,$method){ 
if(!file_exists($path)!fopen($path,$method)){ 
$this->error(模板文件不存在,或没有操作权限); 
returnfalse; 
} 
} 
/** 
*读取文件内容 
* 
*@paramunknown_type$path 
*@returnunknown 
*/ 
functionfile_read($path,$length=0){ 
if(!$this->file_test($path,r+)){ 
$fp=@fopen($path,r+); 
if($length==0){ 
$contents=@fread($fp,filesize($path)); 
}else{ 
$contents=@fread($fp,$length); 
} 
fclose($fp); 
return$contents; 
} 
} 
/** 
*写入文件内容 
* 
*@paramunknown_type$path 
*@paramunknown_type$puts 
*/ 
functionfile_write($path,$puts){ 
if(!$this->file_test($path,w+)){ 
$fp=@fopen($path,w+); 
@fwrite($fp,$puts); 
fclose($fp); 
} 
} 
/** 
*计算文件的hash 
* 
*@paramunknown_type$path 
*@returnunknown 
*/ 
functionfile_hash($path){ 
returnmd5_file($path); 
} 
/** 
*对比模板文件与缓存文件的hash值 
* 
*@paramunknown_type$file 
*@returnunknown 
*/ 
functionmatch_hash($file){ 
$read_hash=$this->file_read($this->cache_dir.$file.$this->cache_suffix,46); 
$html_hash=$this->file_hash($this->tp_dir.$file.$this->tp_suffix); 
if(preg_match(/.$html_hash./i,$read_hash)){ 
returntrue; 
} 
} 
functionaddquote($var){ 
returnstr_replace(\\\,\,preg_replace(/\[([a-zA-Z0-9_\-\.\x7f-\xff]+)\]/s,[\\1],$var)); 
} 
functiontransamp($str){ 
$str=str_replace(&,,$str); 
$str=str_replace(amp;,,$str); 
$str=str_replace(\,,$str); 
return$str; 
} 
functionstripvtags($expr,$statement){ 
$expr=str_replace(\\\,\,preg_replace(/\<\?\=(\\\$.+?)\?\>/s,\\1,$expr)); 
$statement=str_replace(\\\,\,$statement); 
return$expr.$statement; 
} 
} 
$tp=newmmtp(); 
$tp->__setdir(./); 
$tp->__setcdir(./cache/); 
$tp->tp(index1); 
$_GET[it]=sdhkadajksdhajdhkajsdhjkasdjkasdhasjdhkjsadhk; 
$name=2; 
$head=欢迎使用MoMo模板引擎; 
include(./cache/index1.tpl); 
?> 
模板index.html
复制代码 代码如下:{$head}
模板index1.html 
复制代码 代码如下:{templateindex} 
{if$name==1} 
你好 
{else} 
谢谢 
{/if}
这个模板是默默今天下午写的,写的比较仓促,也许存在漏洞,这个版本只是测试版,以后我会逐渐的去完善,先发出来,当作一个前瞻. 
下一篇:中文版