php模板引擎技术简单实现
用了smarty,tp过后,也想了解了解其模板技术是怎么实现,于是写一个简单的模板类,大致就是读取模板文件->替换模板文件的内容->保存或者静态化
tpl.class.php主要解析
assign 方法实现
<span style="color: #008000;"> /*</span><span style="color: #008000;">* * 模板赋值操作 * @param mixed $tpl_var 如果是字符串,就作为数组索引,如果是数组,就循环赋值 * @param mixed $tpl_value 当$tpl_var为string时的值,默认为 null </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">public</span> function assign($tpl_var,$tpl_value=<span style="color: #0000ff;">null</span><span style="color: #000000;">){ </span><span style="color: #0000ff;">if</span>(is_array($tpl_var) && count($tpl_var) > <span style="color: #800080;">0</span><span style="color: #000000;">){ </span><span style="color: #0000ff;">foreach</span> ($tpl_var <span style="color: #0000ff;">as</span> $k =><span style="color: #000000;"> $v) { $</span><span style="color: #0000ff;">this</span>->tpl_vars[$k] =<span style="color: #000000;"> $v; } }elseif($tpl_var){ $</span><span style="color: #0000ff;">this</span>->tpl_vars[$tpl_var] =<span style="color: #000000;"> $tpl_value; } }</span>
fetch 方法实现
<span style="color: #008000;">/*</span><span style="color: #008000;">* * 生成编译文件 * @param string $tplFile 模板路径 * @param string $comFile 编译路径 * @return string </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">private</span><span style="color: #000000;"> function fetch($tplFile,$comFile){ </span><span style="color: #008000;">//</span><span style="color: #008000;">判断编译文件是否需要重新生成(编译文件是否存在或者模板文件修改时间大于编译文件的修改时间)</span> <span style="color: #0000ff;">if</span>(!file_exists($comFile) || filemtime($tplFile) ><span style="color: #000000;"> filemtime($comFile)){ </span><span style="color: #008000;">//</span><span style="color: #008000;">编译,此处也可以使用ob_start()进行静态化</span> $content = $<span style="color: #0000ff;">this</span>-><span style="color: #000000;">tplReplace(file_get_contents($tplFile)); file_put_contents($comFile, $content); } } </span>
简单编译方法:按照规则进行正则替换
<span style="color: #008000;">/*</span><span style="color: #008000;">* * 编译文件 * @param string $content 待编译的内容 * @return string </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">private</span><span style="color: #000000;"> function tplReplace($content){ </span><span style="color: #008000;">//</span><span style="color: #008000;">转义左右定界符 正则表达式字符</span> $left = preg_quote($<span style="color: #0000ff;">this</span>->left_delimiter,<span style="color: #800000;">'</span><span style="color: #800000;">/</span><span style="color: #800000;">'</span><span style="color: #000000;">); $right </span>= preg_quote($<span style="color: #0000ff;">this</span>->right_delimiter,<span style="color: #800000;">'</span><span style="color: #800000;">/</span><span style="color: #800000;">'</span><span style="color: #000000;">); </span><span style="color: #008000;">//</span><span style="color: #008000;">简单模拟编译 变量</span> $pattern =<span style="color: #000000;"> array( </span><span style="color: #008000;">//例如</span><span style="color: #008000;">{$test}</span> <span style="color: #800000;">'</span><span style="color: #800000;">/</span><span style="color: #800000;">'</span>.$left.<span style="color: #800000;">'</span><span style="color: #800000;">\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)</span><span style="color: #800000;">'</span>.$right.<span style="color: #800000;">'</span><span style="color: #800000;">/i</span><span style="color: #800000;">'</span><span style="color: #000000;"> ); $replace </span>=<span style="color: #000000;"> array( </span><span style="color: #800000;">'</span><span style="color: #800000;"><?php echo $this->tpl_vars[\'${1}\']; ?></span><span style="color: #800000;">'</span><span style="color: #000000;"> ); </span><span style="color: #008000;">//</span><span style="color: #008000;">正则处理</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> preg_replace($pattern, $replace, $content); }</span>
display = fetch+echo
<span style="color: #008000;">/*</span><span style="color: #008000;">* * 输出内容 * @param string $fileName 模板文件名 </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">public</span><span style="color: #000000;"> function display($fileName){ </span><span style="color: #008000;">//</span><span style="color: #008000;">模板路径</span> $tplFile = $<span style="color: #0000ff;">this</span>->template_dir.<span style="color: #800000;">'</span><span style="color: #800000;">/</span><span style="color: #800000;">'</span><span style="color: #000000;">.$fileName; </span><span style="color: #008000;">//</span><span style="color: #008000;">判断模板是否存在</span> <span style="color: #0000ff;">if</span>(!<span style="color: #000000;">file_exists($tplFile)){ $</span><span style="color: #0000ff;">this</span>->errorMessage = <span style="color: #800000;">'</span><span style="color: #800000;">模板文件不存在</span><span style="color: #800000;">'</span><span style="color: #000000;">; </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">; } </span><span style="color: #008000;">//</span><span style="color: #008000;">编译后的文件</span> $comFile = $<span style="color: #0000ff;">this</span>->compile_dir.<span style="color: #800000;">'</span><span style="color: #800000;">/</span><span style="color: #800000;">'</span>.md5($fileName).<span style="color: #800000;">'</span><span style="color: #800000;">.php</span><span style="color: #800000;">'</span><span style="color: #000000;">; $</span><span style="color: #0000ff;">this</span>-><span style="color: #000000;">fetch($tplFile,$comFile); <br> include $comFile; }</span>
其他属性
<span style="color: #008000;"> //</span><span style="color: #008000;">模板文件存放位置</span> <span style="color: #0000ff;">private</span> $template_dir = <span style="color: #800000;">'</span><span style="color: #800000;">templates</span><span style="color: #800000;">'</span><span style="color: #000000;">; </span><span style="color: #008000;">//</span><span style="color: #008000;">编译文件存放位置</span> <span style="color: #0000ff;">private</span> $compile_dir = <span style="color: #800000;">'</span><span style="color: #800000;">compiles</span><span style="color: #800000;">'</span><span style="color: #000000;">; </span><span style="color: #008000;">//</span><span style="color: #008000;">左定界符</span> <span style="color: #0000ff;">private</span> $left_delimiter = <span style="color: #800000;">'</span><span style="color: #800000;">{</span><span style="color: #800000;">'</span><span style="color: #000000;">; </span><span style="color: #008000;">//</span><span style="color: #008000;">右定界符 </span> <span style="color: #0000ff;">private</span> $right_delimiter = <span style="color: #800000;">'</span><span style="color: #800000;">}</span><span style="color: #800000;">'</span><span style="color: #000000;">; </span><span style="color: #008000;">//</span><span style="color: #008000;">内部临时变量,存储用户赋值</span> <span style="color: #0000ff;">private</span> $tpl_vars =<span style="color: #000000;"> array(); </span><span style="color: #008000;">//</span><span style="color: #008000;">错误信息</span> <span style="color: #0000ff;">private</span> $errorMessage = <span style="color: #800000;">''</span><span style="color: #000000;">; </span><span style="color: #008000;">/*</span><span style="color: #008000;">* * 修改类属性的值 * @param array $configs 需要修改的相关属性及值 * @return bool </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">public</span><span style="color: #000000;"> function setConfigs(array $configs){ </span><span style="color: #0000ff;">if</span>(count($configs) > <span style="color: #800080;">0</span><span style="color: #000000;">){ </span><span style="color: #0000ff;">foreach</span> ($configs <span style="color: #0000ff;">as</span> $k =><span style="color: #000000;"> $v) { </span><span style="color: #0000ff;">if</span>(isset($<span style="color: #0000ff;">this</span>-><span style="color: #000000;">$k)) $</span><span style="color: #0000ff;">this</span>->$k =<span style="color: #000000;"> $v; } </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">; }</span>
测试
模板文件 testTpl.html
<!DOCTYPE html><html lang=<span style="color: #800000;">"</span><span style="color: #800000;">en</span><span style="color: #800000;">"</span>><head> <meta charset=<span style="color: #800000;">"</span><span style="color: #800000;">UTF-8</span><span style="color: #800000;">"</span>> <title>test_tpl_demo</title></head><body><span style="color: #000000;"> {$name}:{$age}:{$message}</span></body></html>
运行文件 test_tpl.php
<?<span style="color: #000000;">php require </span><span style="color: #800000;">'</span><span style="color: #800000;">Tpl.class.php</span><span style="color: #800000;">'</span><span style="color: #000000;">; $tpl </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> Tpl(); $tplarr </span>=<span style="color: #000000;"> array( </span><span style="color: #800000;">'</span><span style="color: #800000;">name</span><span style="color: #800000;">'</span>=><span style="color: #800000;">'</span><span style="color: #800000;">waited</span><span style="color: #800000;">'</span><span style="color: #000000;">, </span><span style="color: #800000;">'</span><span style="color: #800000;">age</span><span style="color: #800000;">'</span>=><span style="color: #800000;">'</span><span style="color: #800000;">100</span><span style="color: #800000;">'</span><span style="color: #000000;"> ); $tpl</span>-><span style="color: #000000;">assign($tplarr); $tpl</span>->assign(<span style="color: #800000;">'</span><span style="color: #800000;">message</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">this is a demo</span><span style="color: #800000;">'</span><span style="color: #000000;">); $tpl</span>->display(<span style="color: #800000;">'</span><span style="color: #800000;">testTpl.html</span><span style="color: #800000;">'</span><span style="color: #000000;">);</span>?>
输出:waited:100:this is a demo
生成编译文件:972fa4d270e295005c36c1dbc7e6a56c.php