今天闲着没事,看到一篇php模板引擎的文章,感觉写的还是太烦琐了,并且语法也不够简单,于是萌生了自己打造一款超简单实用的模板引擎的念头。按照笔者的想法模板引擎应该具有的特点是:
- 语法简单,最好是php原生语法
- 执行速度快
- 支持缓存编译,这点很重要哦,可以节约很多模板解析时间~
思路有了,一切开始就绪,首先是设计模板引擎的语法,根据思路,语法设计如下(注意:所有模板语法占用一行):
#$var_name //变量输出,当时支持数组之类的啦
#if($cond=1){
.....html内容
#}
#foreach($arr as $v){
<li>
#$v
</li>
#}
下面给出代码:
<?php
class template{
public $delim = "#";
public $template_path = "./template";
public $template_cache = "./cache";
public $cache_time = 86400;
public $template_surfix = ".html";
private $current_template = "";
private $cache_file = "";
private $data = array();
public function __get($name){
return isset($this->data[$name])?$this->data[$name]:false;
}
public function __set($name,$value){
$this->data[$name] = $value;
}
public function assign($name,$value){
$this->$name = $value;
}
public function display($template){
$this->current_template = $template;
if($this->chk_cache()){
@extract($this->data);
include ($this->cache_file);
}
else{
$this->compile();
}
}
private function token($str){
$tok = strtok($str, $this->delim);
while ($tok !== false) {
$ret = substr($tok,0,strpos($tok,"\n"));
$tok = strtok($this->delim);
$retarr[$ret] = token_get_all("");
}
return $retarr;
}
private function parse($str){
$retarr = $this->token($str);
foreach($retarr as $key=>$v){
$tokenname = @token_name($v[1][0]);
switch($tokenname){
case 'T_VARIABLE':
$str = str_replace("#".$key,"<?php echo {$v[1][1]} ?>",$str);
break;
default:
$str = str_replace("#".$key,"<?php $key ?>",$str);
}
}
return ($str);
}
private function compile(){
$source = file_get_contents($this->template_path."/".$this->current_template.$this->template_surfix);
$result = $this->parse($source);
file_put_contents($this->cache_file,$result);
@extract($this->data);
include ($this->cache_file);
}
private function chk_cache(){
$this->cache_file = $this->template_cache."/".md5($this->current_template).".php";
if(file_exists($this->cache_file) && time()-filemtime($this->cache_file)<$this->cache_time){
return true;
}
return false;
}
}
?>
测试代码:
<?php
include "template.class.php";
$t = new template();
$t->assign('test','is a test value');
$t->assign('tdshow',1);
$t->display('index');
?>
模板:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title></title>
</head>
<body>
#$test
<table>
#if($tdshow=='1'){
<tr>
<td>td is show</td>
</tr>
#}
</table>
<ul>#for($i=0;$i<10;$i++){
<li>
#$test
</li>
#}
</ul>
</body>
</html>
需要改进的地方:
- 暂不支持子模板
- 语法必须当独一行,否则会出错
- 笔者会在后续版本中开发新功能,并力求简单实用,争取在100行代码内完成这些任务!
毕竟花的时间太短,只有1个小时吧^_^,对于一个成熟的代码来说,开发时间实在少的可怜,不过为大家提供一种新思路,个人觉得,没必要一提到php模板引擎就一定要用到正则表达式嘛~




很简单。。不错。。。。
| 2010年08月30日 @ 10:56 下午
请提取出缓存的代码,如果能给这个机制加全注释的话万分感谢
| 2011年07月31日 @ 1:35 下午