自己写一个简单的模版引擎

简介:

   现在离职在家,突然发现没什么事儿做了,就研究研究了smarty,写了一个简单的搜索引擎。包含

assign赋值,display模版解析的方法,

新建一个MyTpl.class.php(其他名称也可以)

   代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<?php
class  MyTpl{
     //初始化函数
     function  __construct( $template_dir = 'templates/' , $compile_dir = 'templates_c' ){
         $this ->template_dir=rtrim( $template_dir , '/' ). '/' ;
         $this ->compile_dir=rtrim( $compile_dir , '/' ). '/' ;
         $this ->tpl_vars= array ();
     }
                                                                                     
     //赋值函数
     function  assign( $tpl_var , $value =null){
         if  ( $tpl_var != '' )    $this ->tpl_vars[ $tpl_var ]= $value ;
     }
                                                                                     
     //模版解析
     function  display( $fileName ){
         $tplFile = $this ->template_dir. $fileName ;
         if  (! file_exists ( $tplFile ))      return  false;
                                                                                         
         $comFileName = $this ->compile_dir. 'com_' . basename ( $tplFile ). '.php' ;
                                                                                         
         if  (! file_exists ( $comFileName )|| filemtime ( $comFileName )< filemtime ( $tplFile )){
             $repContent = $this ->tpl_replace( file_get_contents ( $tplFile ));
             $handle = fopen ( $comFileName 'w+' );
             fwrite( $handle $repContent );
             fclose( $handle );
         }
         require_once  $comFileName ;
     }
                                                                                     
     //模版替换函数
     private  function  tpl_replace( $content ){
         $pattern = array (
                 '/<\{\s*\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-xff]*)\s*\}>/i' ,      //解析变量
                 '/<\{\s*if\s*(.+?)\s*\}>(.+?)<\{\s*\/if\s*\}>/ies' ,                          //if标签解析
                 '/<\{\s*else\s*if\s*(.+?)\s*\}>/' ,                                                                 //elseif解析
                 '/<\{\s*else\s*\}>/' ,                                                                                  //else解析
                 '/<\{\s*loop\s+\$(\S+)\s+\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\s*\}>(.+?)<\{\\s*\/loop\s*}>/is' ,      //匹配loop标签
                 '/<\{\s*loop\s+\$(\S+)\s+\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\s*=>\s*\$(\S+)\s*\}>(.+?)<\{\s*\/loop\s*\}>/is>/' , //遍历loop中的键和值
                 '/<\{\s*include\s+[\"\']?(.+?)[\"\']?\s*\}>/ie' ,                           //匹配include
         );
         //替换成php
         $replacement = array (
                 '<?php echo $this->tpl_vars["${1}"]?>' ,                 //变量替换
                 '$this->stripvtags(\'<?php if(${1}){?>\',\'${2}<?php}?>\')' ,
                 '$this->stripvtags(\'<?php } elseif(${1}) { ?>\',"")' ,
                 '<?php } else { ?>' ,
                 '<?php foreach($this->tpl_vars["${1}"] as $this->tpl_vars["${2}"]) { ?>${3}<?php } ?>' ,
                 '<?php foreach($this->tpl_vars["${1}"] as $this->tpl_vars["${2}"]=>$this->tpl_vars["${3}"]){?>$(4)<?php } ?>' ,
                 'file_get_contents($this->template_dir."${1}")'
         );
                                                                                         
         $repContent =preg_replace( $pattern $replacement $content );
         if  (preg_match( '/<\{([^(\}>)]{1,})\}>/' $repContent )){
             $repContent = $this ->tpl_replace( $repContent );
         }
         return  $repContent ;
     }
     //替换条件语句中对应的值
     private  function  stripvtags( $expr , $statement ){
         $var_pattern = '/\s*\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\s*/is' ;
         $expr =preg_replace( $var_pattern '$this->tpl_vars["${1}"]' $expr );
         $expr = str_replace ( "\\\"" "\"" $expr );
         $statement = str_replace ( "\\\"" "\"" $statement );
         return  $expr . $statement ;
     }
}


   以上很简单,就是赋值,然后做模版解析以后再输出,最复杂的一部分就是正则替换这一部分,写了很久,有时间还是借鉴一下smarty的吧。

   接下来就测试一下,新建一个inde.php

1
2
3
4
5
require_once  'plugins/MyTpl.class.php' ;
$Tpl = new  MyTpl();
$title = '第一个标题' ;
$Tpl ->assign( 'title' , $title );
$Tpl ->display( 'index.tpl' );

并且新建templates目录,templates_c目录其他根据实际情况来写,然后在templates中新建一个index.tpl,写上相应的代码,我只是做一个简单的测试,

1
2
3
4
5
6
< html >
     < head >< title ><{$title}></ title ></ head >
     < body >
     <{$title}>
     </ body >
</ html >

然后在浏览器中预览,就可以实现,我写的正则替换里,也包括一个loop的foreach替换标签。大家可以继续扩展完善,我也会继续完善一套自己的模版引擎。










本文转自 3147972 51CTO博客,原文链接:http://blog.51cto.com/a3147972/1253462,如需转载请自行联系原作者
目录
相关文章
|
5月前
|
前端开发 JavaScript Java
前端最常用的模板引擎-Handlebars
前端最常用的模板引擎-Handlebars
56 0
|
Java Spring
常见的模版引擎
常见的模版引擎
62 0
|
Java 程序员 Apache
模板引擎——FreeMarker初体验
FreeMarker 是一款模板引擎:一种基于模板的、用来生成输出文本(任何来自于 HTML格式的文本用来自动生成源代码)的通用工具。
|
开发框架 Java
【Freemarker】自己懒得写HTML?那就来试试模板引擎
对于JavaWeb的最后一部分内容我们介绍一款模板引擎,至于模板引擎的概念我们也会在正文中进行叙述的。
【Freemarker】自己懒得写HTML?那就来试试模板引擎
|
Java
JSP第七篇【自定义标签就是如此简单】(修订版)(二)
为了简化标签开发的复杂度,在JSP 2.0中定义了一个更为简单、便于编写和调用的SimpleTag接口来实现标签的功能。。 一般来说,实现了SimpeTag接口的标签称之为简单标签
69 0
JSP第七篇【自定义标签就是如此简单】(修订版)(二)
|
Java 容器
JSP第七篇【自定义标签就是如此简单】(修订版)(一)
为了简化标签开发的复杂度,在JSP 2.0中定义了一个更为简单、便于编写和调用的SimpleTag接口来实现标签的功能。。 一般来说,实现了SimpeTag接口的标签称之为简单标签
112 0
JSP第七篇【自定义标签就是如此简单】(修订版)(一)
|
Java
JSP第七篇【简单标签、应用、DynamicAttribute接口】(四)
上一篇博客中我已经讲解了传统标签,想要开发自定义标签,大多数情况下都要重写doStartTag(),doAfterBody()和doEndTag()方法,并且还要知道SKIP_BODY,EVAL_BODY等等的变量代表着什么,在什么方法中使用。这样实在是太麻烦了!
195 0
JSP第七篇【简单标签、应用、DynamicAttribute接口】(四)
|
Java
JSP第七篇【简单标签、应用、DynamicAttribute接口】(二)
上一篇博客中我已经讲解了传统标签,想要开发自定义标签,大多数情况下都要重写doStartTag(),doAfterBody()和doEndTag()方法,并且还要知道SKIP_BODY,EVAL_BODY等等的变量代表着什么,在什么方法中使用。这样实在是太麻烦了!
89 0
JSP第七篇【简单标签、应用、DynamicAttribute接口】(二)
|
Java
JSP第七篇【简单标签、应用、DynamicAttribute接口】(三)
上一篇博客中我已经讲解了传统标签,想要开发自定义标签,大多数情况下都要重写doStartTag(),doAfterBody()和doEndTag()方法,并且还要知道SKIP_BODY,EVAL_BODY等等的变量代表着什么,在什么方法中使用。这样实在是太麻烦了!
84 0
JSP第七篇【简单标签、应用、DynamicAttribute接口】(三)
|
Java 容器
JSP第七篇【简单标签、应用、DynamicAttribute接口】(一)
上一篇博客中我已经讲解了传统标签,想要开发自定义标签,大多数情况下都要重写doStartTag(),doAfterBody()和doEndTag()方法,并且还要知道SKIP_BODY,EVAL_BODY等等的变量代表着什么,在什么方法中使用。这样实在是太麻烦了!
114 0
JSP第七篇【简单标签、应用、DynamicAttribute接口】(一)