今天闲着没事,看到一篇php模板引擎的文章,感觉写的还是太烦琐了,并且语法也不够简单,于是萌生了自己打造一款超简单实用的模板引擎的念头。按照笔者的想法模板引擎应该具有的特点是:
语法简单,最好是php原生语法
执行速度快
支持缓存编译,这点很重要哦,可以节约很多模板解析时间~
思路有了,一切开始就绪,首先是设计模板引擎的语法,根据思路,语法设计如下(注意:所有模板语法占用一行):
#$var_name //变量输出,当时支持数组之类的啦
#if($cond=1){
.....html内容
#}
#foreach($arr as $v){
#$v
#}
下面给出代码:
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)cache_time){
return true;
}
return false;
}
}
?>
测试代码:
include "template.class.php";
$t = new template();
$t->assign('test','is a test value');
$t->assign('tdshow',1);
$t->display('index');
?>
模板:
#$test
#if($tdshow=='1'){
td is show#}
#$test
#}
需要改进的地方:
暂不支持子模板
语法必须当独一行,否则会出错
笔者会在后续版本中开发新功能,并力求简单实用,争取在100行代码内完成这些任务!
毕竟花的时间太短,只有1个小时吧^_^,对于一个成熟的代码来说,开发时间实在少的可怜,不过为大家提供一种新思路,个人觉得,没必要一提到php模板引擎就一定要用到正则表达式嘛~