码迷,mamicode.com
首页 > 其他好文 > 详细

做一个模仿Smarty的简易模版

时间:2015-11-03 09:16:26      阅读:317      评论:0      收藏:0      [点我收藏+]

标签:

---恢复内容开始---

今天终于学习完了一个慕课网的正则表达式的视频,感觉挺不错的,推荐给大家

技术分享

 

下面是我学习写的一些代码

首先要先明白什么是Smarty模版。

这种模版就是将一个文件中的代码运用正则替换为令一段代码以供下一步的运行。也就是说可以通过这个模版来省略很多语法,结构上面的规则,从而很好的将前端开发和后端开发分离,不需什么都懂,在这个山寨的模版里面主要是将前端的HTML代码中的一些字段替换成可被运行的PHP代码,完成给用户的最后的输出。

 

 

好,首先是新建的项目,既然有编译,就有个源文件和编译后存放的文件夹,如下图

技术分享

在这个目录下,新建一个PHP文件,命名为template.class.php,写编译模版类

首先,定义一个类

1 class template{
2     
3     private $templateDir;                        //源文件目录
4     private $compileDir;                        //编译后的文件目录
5     private $leftTag = ‘{#‘;                    //正则模式左标记
6     private $rightTag = ‘#}‘;                    //右标记
7     private $currentTemp = ‘‘;                    //正在编译的模板文件名
8     private $outputHtml;                        //存放正在编译中的模板文件中的HTML代码(存后替换输出)
9     private $varPool = array();                    //自己定义的变量池

定义一些私有属性,每个属性都在背后做了注释,其中标记并不指定,只是给个默认初始值,用户调用时还可以自己定义的

接下来写一个构造函数

public function __construct($templateDir,$compileDir,$leftTag = null, $rightTag = null){
        $this->templateDir = $templateDir;
        $this->compileDir= $compileDir;
        if(!empty($leftTag)) $this->leftTag= $leftTag;
        if(!empty($rightTag)) $this->rightTag = $rightTag;           //给出源文件目录,编译文件目录,可自己定义界定符
    }

这个构造函数用来初始化对象的一些基本属性,包括要编译的源文件目录,结果存放目录,还有正则匹配的标记等,用户可在这里定义自己想要的标记

然后写一些基础的方法,为之后的编译服务,首先是给变量池中赋值,取值

    public function assign($tag,$var){
        $this->varPool[$tag] = $var;                        //给变量池里定义变量
        
    }

    public function getVar($tag){
        return $this->varPool[$tag];                        //获取变量值
    }

接下来是找到要编译的源文件的目录,并获取文件内容,传给对象的基本属性outputhtml,为后续编译准备

    public function getSourceTemplate($templateName,$ext = ‘.html.‘){
        $this->currentTemp = $templateName;                              //将要编译的文件名传给对象的当前编译文件私有属性
        $sourceFilename = $this->templateDir.$this->currentTemp.$ext;    //得到完整的源文件路径
        $this->outputHtml = file_get_contents($sourceFilename);            //把文件中的内容传给对象,即对象获取文件中的代                                                                    码
    }                                                                    //这个方法用来获取模板的源文件

方法的第二个参数只是个默认值,可以修改。第一条语句是将文件名传给对象的currentTemp私有属性储存,第二条语句是连接起目标文件的完整目录。后续用一个file_get_contents函数获取内容,传给对象。

准备工作就绪,接下来是正则匹配替换方法,也是最核心的部分

                                    //最核心的方法
    public function compileTemplate($templateName = null,$ext = ‘.html‘){
        $templateName = empty($templateName)   ? $this->currentTemp :$templateName;    //先得到要编译的源文件名称,如果调用方法时没给,则使用私有属性中的文件名

        $pattern = ‘/‘.preg_quote($this->leftTag);
        $pattern.= ‘ *\$([a-zA-Z_]\w*) *‘;
        $pattern.= preg_quote($this->rightTag).‘/‘;
        $this->outputHtml = preg_replace($pattern,‘<?php echo $this->getVar(\‘$1\‘);?>‘,$this->outputHtml); //$1,匹配到的第一个子模式中的内容,\\1也可以

首先得到完整准确目录,与之前的语句相同。接着就是正则模式的书写。preg_quote是为了防止定义的标记中有正则运算符,做一个转换。‘ *‘这个是为了给予前端代码书写更多空间,允许一些无用的空格出现。子模式为要匹配到的内容,方括号里是php变量的书写规则,字母或下划线开头。

接着就使用了一个preg_replace语句开始编译,按$pattern模式将匹配到的outputHtml中的内容替换成php输入语句,‘$1‘这个是指前面正则匹配中匹配到的第一个子模式中的内容,用这个内容就可以找到在变量池中想要输出的内容。

 接下来就是最后的一个方法了,就是把内容显示出来的方法

public function display($templateName = null,$ext = ‘.html‘){
        $templateName = empty($templateName) ? $this->currentTemp : $templateName;
        include_once $this->compileDir.md5($templateName).$ext;         
    }

获取文件名,连接路径,用include_once函数输出便可,至此我们的正则模版就定义好了。

接下来在原目录下新建一个php文件,命名为index.php

 

技术分享

 

index.php中代码如下

<?php
    
require_once(‘template.class.php‘);

$baseDir = str_replace(‘\\‘,‘/‘,dirname(__FILE__));  //当前的目录,把\替换成/,__FILE__是一个魔术常量,表示当前文件目录
$temp = new template($baseDir.‘/source/‘,$baseDir.‘/compiled/‘);    //实例化一个模版对象,给源目录和编译放置目录

$temp->assign(‘test‘,‘imooc女神‘);   
$temp->assign(‘pagetitle‘,‘山寨版smarty‘);                    //给变量池中加变量

$temp->getSourceTemplate(‘index‘);
$temp->compileTemplate();
$temp->display();



?>

与模版关联,后得到当前目录,创建一个对象,将要替换的值加入变量池,得到源文件中要编译的文件的目录(此处我们的例子是index.html),开始编译,然后输出

技术分享我们是在source下写了一个html页面,内容如下

<!DOCTYPE HTML>
<html>
 <head>
 <meta charset="utf-8">
  <title>{#$pagetitle#}</title>

 </head>

 <body>
  模版引擎测试:{#$test#}
 </body>
</html>

经过编译后在compiled下得到一个新的html文件,文件名经过加密,打开后得到如图效果

技术分享    技术分享技术分享

可见源文件中的$pagetitle,$test中已被替换成php中的输出语句,在浏览器中也显示出了应有的效果,我们的一个模仿Smarty就做好的

 

 

实际上的Smarty模版功能远比这个强大,但我们知其一便能知其二,慢慢添加完善,我们的模版也能很强大,哈哈!

 

做一个模仿Smarty的简易模版

标签:

原文地址:http://www.cnblogs.com/ly550275752/p/4932069.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!