zoukankan      html  css  js  c++  java
  • 深入浅出之Smarty模板引擎工作机制(二)

    源代码下载地址:深入浅出之Smarty模板引擎工作机制
    接下来根据以下的Smarty模板引擎原理流程图开发一个自己的模板引擎用于学习,以便加深理解。

      Smarty模板引擎的原理,其实是这么一个过程:
      把模板文件编译成php文件,然后每次都去读取下模板的修改时间,没有修改就不编译。然后include这个“编译”后的PHP文件。
      所谓编译也就是模板用正则替换成含PHP代码的过程。
      实际上并不会每次请求都编译,所以性能尚可。

       模板文件和php程序文件经过模板引擎的编译后合成为一个文件,即编译后的文件。

    接下来,我们根据该原理流程写一个简单的模板引擎。。。。。。

      先贴上核心代码:

      Smarty.class.php文件

    复制代码
    <?php
    class Smarty{
    public $template_dir;//模板目录
    public $compile_dir;//编译目录
    public $arr=array();//定义一个数组,用以存放assign中的第二个参数传过来的值
    public function __construct($template_dir="../templates",$compile_dir="../templates_c"){
    $this->template_dir=$template_dir;//模板目录
    $this->compile_dir=$compile_dir; //编译目录
    }
    public function assign($content,$replacment=null){
    if($content!=""){ //如果指定模板变量,才将要赋的值存储到数组中
    $this->arr[$content]=$replacment;
    }
    }
    public function display($page){
    $tplFile=$this->template_dir."/".$page;//读取模板文件,注意:如果模板目录下还有子目录,记得要写完整,比如,$smarty->display('Default/index.tpl')
    if(!file_exists($tplFile)){
    return;
    }
    $comFile=$this->compile_dir."/"."com_".$page.".php";
    $tplContent=$this->con_replace(file_get_contents($tplFile));//将smarty标签替换为php的标签
    file_put_contents($comFile,$tplContent);
    include $comFile;
    }
    public function con_replace($content){
    $pattern=array(
    '/<{s*$([a-zA-Z_][a-zA-Z_0-9]*)s*}>/i'
    );
    $replacement=array(
    '<?php echo $this->arr["${1}"] ?>'
    );
    return preg_replace($pattern,$replacement,$content);
    }
    }
    ?>
    复制代码

     

    Smarty.class.php代码解释:

    • $template_dir  指定模板文件的目录
    • $compile_dir   指定编译后的模板文件的目录
    • 构造函数 

        public function __construct($template_dir="../templates",$compile_dir="../templates_c")

        {                  

               $this->template_dir=$template_dir;

               $this->compile_dir=$compile_dir;

        }

        默认情况下,Smarty模板引擎将把templates目录用于存放模板文件,templates_c用于存放编译后的文件

    • assign($content,$replacment=null)函数的工作机制是将每次要传递给模板中的变量的值通过语句:$this->arr[$content]=$replacment;保存到数组中。  

         那为何要$replacement的值保存到数组中呢?

         其实内部操作是这么一个流程:将$replacement值保存到数组--->读取模板文件(index.dwt,由display函数完成)--->将数组中的值匹配给模板文件中的变量(由con_replace()函数完成)--->将替换后的模板文件写入到编译文件中(com_index.dwt.php)--->输出编译后的PHP文件

    • dispaly($page)函数接收一个参数,即要输出的模板文件(index.dwt)
      • 首先,将模板文件的路径赋给$tplFile($tplFile=$this->template_dir."/".$page)  
      • 判断模板文件是否存在,如果不存在,就没必要加载了,直接return
      • 指定一个编译文件,以便存放替换变量后的模板文件
      • 通过函数file_get_contents()读取模板文件,并通过函数conf_replace()替换掉模板中的smarty标签
      • 将替换变量后的模板文件通过file_put_contents()写入到编译文件中
      • 将编译后的文件include进来,即可输出编译后的文件
    • 函数con_replace($content)用于替换模板文件(index.dwt)中的变量,即将php中的变量值赋给模板中的变量    
      • 通过一个可以匹配<{$title}>形式的正则表达式匹配模板文件中的内容,并将匹配到的值替换为<?php echo $title?>的形式
      • 匹配到内容,并将替换后的内容返回
    复制代码
    /*Smarty.ini.php文件:用于完成初始化smarty的工作*/
    <?php
    include "./libs/Smarty.class.php";
    $tpl=new Smarty();
    $tpl->template_dir="./Tpl";
    $tpl->compile_dir="./Compile";
    ?>
    复制代码
    复制代码
    <!--模板文件-->
    <!DOCTYPE HTML>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title><{$title}></title>
    </head>
    <body>
    <p>内容:<{$content}></p>
    <p>作者:<{$auth}></p>
    <p>网址:<{$website}></p>
    </body>
    </html>
    复制代码
    复制代码
    /*index.php文件*/
    <?php
    include "./Smarty.ini.php";
    $title="深入浅出之Smarty模板引擎工作机制";
    $content="Smarty模板引擎工作机制流程图";
    $auth="MarcoFly";
    $website="www.MarcoFly.com";
    $tpl->assign("title",$title);
    $tpl->assign("content",$content);
    $tpl->assign("auth",$auth);
    $tpl->assign("website",$website);
    $tpl->display("index.dwt");
    ?>
    复制代码

    该index.php就是PHP程序员编写的,可以从数据库中获取各种想要的数据,并保存到变量中,然后简单的调用assign()函数将数据保存到数组中,并通过display()函数将编译文件输出

    注:此编译文件是php文件,通过服务器端执行,将结果输出的客户端的浏览器上

    分析到这里,我们回过头来分析下在深入浅出之Smarty模板引擎工作机制(一)中给出的关于编译后的文件代码:

    复制代码
    <!DOCTYPE HTML>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title><?php echo $this->arr["title"] ?></title>
    </head>
    <body>
    <p>内容:<?php echo $this->arr["content"] ?></p>
    <p>作者:<?php echo $this->arr["auth"] ?></p>
    <p>网址:<?php echo $this->arr["website"] ?></p>
    </body>
    </html>
    复制代码

    由于我们已经通过assign()函数,将要赋给模板标签中变量的值保存到了数组中了,即此时编译后的模板文件,可以直接输出该数组中的值了。

    举个例子:

    $title="深入浅出之Smarty模板引擎工作机制";    
    $tpl->assign("title",$title);
    当执行了以上两句代码后,在数组$arr中就存放着下标为:title,值为:深入浅出之Smarty模板引擎工作机制的关联数组了。
    此时,就可以直接通过$this->arr['title']直接输出该数组的值。
    至于对如何从<{$title}>  ---> <?php echo $this->arr['title']?> 的转换,不懂的读者可以再仔细看下con_replace()函数

    有了以上几个文件之后,我们在浏览器中访问index.php文件将得到以下结果:

    到此,我们“开发”了一个自己的模板引擎,并且测试成功,当然,这只是供交流学习之用。如果你觉得这篇文章对你了解smarty模板引擎的工作机制有所帮助的话,请帮忙顶一顶哈O(∩_∩)O~

    文章出自:WEB开发_小飞

    转载请注明出处:http://www.cnblogs.com/hongfei/archive/2011/12/10/Smarty-two.html

  • 相关阅读:
    IE7下总提示" 缺少标识符、字符串或数字"
    #pragma 用法
    破解win7开机密码
    教你怎么样设计一块好的PCB板精华教程
    Object reference not set to an instance of an object. 'Infinity' is not a valid value for property 'width'.
    验证时出错,HRESULT = '8000000A'
    WIN7打补丁后VS2012出现版本不兼容
    VS的快捷键
    WPF学习记录1:ListView的一个模板
    使用Xposed Installer实现Android Hook
  • 原文地址:https://www.cnblogs.com/AloneSword/p/3513910.html
Copyright © 2011-2022 走看看