最近在开发的时候,遇到了在有html模板的情况下,每天生成数据报表的需求,如果用框架太重了,就想自己简单的模板来实现,这样简单实用,顺便记录下原理。
  一. 模板引擎原理
     php是网页内嵌型的语言,利用〈?php ?〉标签嵌入到html文本中,然后由php的解释器去执行,动态生成页面。 但是对于大型的web应用,一般分为前端, 后台业务逻辑,及数据层。为了项目协作和分工,当然需要将前端和业务逻辑分离,前端专注于界面展示,后端程序负责逻辑处理。 这样使得改变程序的逻辑内容不会影响到前端人员的页面设计,前端人员重新修改页面不会影响到程序的程序逻辑,这在多人合作的项目中显的尤为重要。

分离之后的两部分怎么实现连接呢? 逻辑层的数据如何传递给模板页面呢? 模板页面的动态数据项采用什么规则预先展示呢?

这是就需要这样一个“桥梁”来解决这个问题,即 模板引擎。

 一般来说需要两个类来实现,分别是模板引擎入口类和模板解析类。 mytpl.class.php文件通常定义一个类MyTpl,类中需定义一个数组tpl_var[]用于存放tpl.html中自定义内容标签的参数。MyTpl.Compile.class.php,解析模板文件,的是将tpl.hml中无法识别的的内容标签转换成PHP语句,编译成“templates_c”文件夹下的tpl_c.html中。 

所以一般的模板引用步骤为:

include  “mytpl.class.php文件”;//加载模板引擎$tpl = new MyTpl();//实例化一个模板类$title = “标题”;$content = “内容”;$tpl->assign(“title”,$title);//调用模板类中的方法,分配变量$tpl->assign(“content”,$content);$tpl->display(“tpl.html”);//调用模板类中的方法,用于显示编译后的内容

整个流程如图所示:

 

 二. 模板引擎简单实现

以下实现了一个最简单的模板引擎,不含模板解析类:

tpl.html:<html><body><?php echo $str ?><br /><?php print_r($arr) ?></body></html>
Mytpl.php:
<?php//include  包含其他文件
//extract  的作用:从数组中将变量导入到当前的符号表,键做变量,值做值!class Mytpl {        public $tpl_vars;        public $key;        public $val;        public function assign($tpl_var,$value){                if (is_array($tpl_var)) {                        foreach ($tpl_var as $_key => $_val) {                                if ($_key != '') {                                        $this->tpl_vars[$_key] = $_val;
                                }
                        }
                } else {                        if ($tpl_var != '') {                                $this->tpl_vars[$tpl_var] = $value;
                        }
                }
        }        public function display($tpl){                $this->assign($this->key,$this->val);                extract($this->tpl_vars);                if(file_exists($tpl)){  //模板存在就加载文件。
                        //include $tpl;
                        ob_start();                        include $tpl;                        $contents = ob_get_contents();                        ob_end_clean();                        return $contents;
                }else{                        return false;
                }
        }
}$tpl = new Mytpl;$arr = array('a'=>'aaaaaaa','b'=>array('a'=>'111111','b'=>'22222','c'=>'3333'),'c'=>'ccccccc','d'=>'dddddd','e'=>'eeeee');$str = '我是字符串';$tpl->assign('arr',$arr);$tpl->assign('str',$str);$message =  $tpl->display('tpl.html');echo $message;?>

其中使用到了extract函数,从数组中将变量导入到当前的符号表,键做变量,值做值!

同时导入模板使用了include 函数,从include该处开始,调用文件在该行处可用的任何变量在被调用的文件中也都可用。不过所有在包含文件中定义的函数和类都具有全局作用域。当一个文件被包含时,语法解析器在目标文件的开头脱离 PHP 模式并进入 HTML 模式,到文件结尾处恢复。由于此原因,目标文件中需要作为 PHP 代码执行的任何代码都必须被包括在有效的 PHP 起始和结束标记之中。(所以需要模板解析类编译模板)。同时将inlcude的文件“包含”到一个变量中的方法是用输出控制函数结合 include 来捕获其输出。

 

如果template文件没有改动,那麽该模板文件就不需要被重新编译,所以可以在模板引擎中添加缓存机制,提升访问速度。

Smarty是一个使用PHP写出来的模板引擎,是目前业界最著名的PHP模板引擎之一,定义了smarty的语法规则和缓存等特性,性能和使用性都非常好。

同时可以参考这个smart的简单实现http://www.cnblogs.com/isuhua/archive/2013/04/13/3019377.html