我们将对比使用smarty模板引擎和没使用smarty模板引擎的两种开发方式的区别,并动手开发一个自己的模板引擎,以便加深对smarty模板引擎工作机制的理解。
在没有使用Smarty模板引擎的情况下,我们都是将PHP程序和网页模板合在一起编辑的,好比下面的源代码:
~~~
<?php$title="深处浅出之Smarty模板引擎工作机制";$content="Smarty模板引擎原理流程图";$auth="MarcoFly";$website="www.MarcoFly.com";?><!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title><?php echo $title?></title></head><body><p>内容:<?php echo $content?></p><p>作者:<?php echo $auth?></p><p>网址:<?php echo $website?></p></body></html>
~~~
输出到浏览器的结果截图:
![](http://pic002.cnblogs.com/images/2011/350329/2011121022394428.jpg)
查看HTML源代码:
~~~
<!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>深处浅出之Smarty模板引擎工作机制</title></head><body><p>内容:Smarty模板引擎原理流程图</p><p>作者:MarcoFly</p><p>网址:www.MarcoFly.com</p></body></html>
~~~
程序比较小的情况下这种开发方式尚且不方便,一旦要开发一个大的WEB项目,就必须得使用到模板引擎。
~~~
使用模板引擎的情况下:
~~~
~~~
我们的开发方式将有所改变,美工人员只管做模板,后台开发人员专心写自己的程序。
~~~
~~~
一个web项目就可以分为模板文件和PHP程序了
~~~
~~~
比如:
~~~
~~~
美工人员就可以这样编辑网页模板文件:
~~~
~~~
index.dwt源代码
~~~
~~~
<!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>
~~~
~~~
而后台WEB开发人员可以专注于PHP代码的书写:
~~~
~~~
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");?>
~~~
~~~
从以上两段简单的演示代码可以看出,前台模板文件没有涉及到任何关于PHP的代码,只有几个看似陌生的标签<{$title}>和<{$content}>,而后台的php程序代码也没有涉及到前台的HMTL代码
~~~
~~~
参考下图对比这两种开发方式的区别
~~~
![](http://pic002.cnblogs.com/images/2011/350329/2011121018464280.gif)
~~~
通过对比,我们得出结论:在使用模板引擎后,原先需要使用PHP编写的地方,现在只需要用模板引擎提供标签的形式来代替了。
~~~
~~~
注:Smarty模板引擎默认的标签形式是{$xxx},如,{$title},{$content}
~~~
~~~
当然我们可以初始化为自己想要的标签形式,如我将其初始化为:<{$xxx}>的形式),如,<{$title}>、<{$content}>
~~~
~~~
不知各位看官有木有觉得奇怪,<{$title}>、<{$content}>根本就不是PHP的语法形式,那最终又是如何被输出到客户的浏览器中的,是否另有玄机?带着这个疑问,我们继续深究......
~~~
~~~
其实,这一切的一切都是由Smarty模板引擎这双神秘的手在“暗中操作”着,经过Smarty模板引擎的“暗中操作”之后,起初的模板文件(index.dwt)经过Smarty“成功手术”之后,被改造为能在服务器端执行的PHP代码文件。
~~~
~~~
想看看模板文件(index.dwt)和后台的PHP程序(index.php)经过“手术”(即编译)之后的庐山真面目吗?
~~~
~~~
在此贴上经过模板引擎编译之后的编译文件的源代码:
~~~
~~~
<!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>
~~~
~~~
看到这里,各位看官是否恍然大悟,原来Smarty模板引擎的工作就是:将前台美工人员编写的模板文件(index.dwt)和后台开发人员编写的PHP程序(index.php)整合在一起,经过编译这一步骤之后,原先的模板标签被替换成了php代码。
~~~
~~~
为了方便大家理解,我简单的做了一张代码流程图:
~~~
![](http://pic002.cnblogs.com/images/2011/350329/2011121021571753.gif)
~~~
接下来根据以下的Smarty模板引擎原理流程图开发一个自己的模板引擎用于学习,以便加深理解。
~~~
![](http://pic002.cnblogs.com/images/2011/350329/2011121021105620.gif)
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用于存放编译后的文件
那为何要$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中的变量值赋给模板中的变量
* 通过一个可以匹配形式的正则表达式匹配模板文件中的内容,并将匹配到的值替换为的形式
* 匹配到内容,并将替换后的内容返回
~~~
/*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模板引擎工作机制(一)**](http://www.cnblogs.com/hongfei/archive/2011/12/10/Smarty-one.html)中给出的关于编译后的文件代码:
~~~
<!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文件将得到以下结果:
![](http://pic002.cnblogs.com/images/2011/350329/2011121021375145.jpg)
到此,我们“开发”了一个自己的模板引擎,并且测试成功,当然,这只是供交流学习之用。
- PHP学习
- PHP应用
- PHP函数总结整理
- 39个对初学者非常有用的PHP技巧
- 深入浅出之Smarty模板引擎工作机制
- 数组操作
- file操作的常用方法
- PHP字符串输出之Heredoc说明
- require(_once)和include(_once)的理解
- PHP提高效率的几点
- php无限遍历目录
- 53个要点提高PHP编程效率
- THINKPHP
- THINKPHP 常见的问题
- 微信
- 微信公众号接口
- 微信小程序开发资料收集
- 微信小程序开发:MINA
- 通过微信小程序看前端
- 微信小程序开发初体验
- 微信小程序 Demo(豆瓣电影)
- API应用
- 支付宝
- 二维码转换
- 前端开发
- HTML5
- CSS
- 七种css方式让一个容器水平垂直居中
- JavaScript
- JavaScript奇技淫巧44招
- JavaScript笔记
- 后端开发
- Node
- SQL数据库
- 服务维护
- git使用
- Git入门私房菜
- MAC终端维护
- VIM命令大全
- 开发规范
- 智能手机屏幕的秘密
- 超实用六步透视网易设计规范(附完整PDF下载)
- UI设计常用字体规范
- APP界面切图命名和文件整理规范
- 网页UI视觉设计规范
- ios视觉设计规范说明
- 开发APP时需要注意的原则
- 移动端APP设计初步入门
- Axure
- 基础操作
- 基础1-10
- 基础11-20
- 基础21-30
- 基础31-40
- 基础41-50
- 基础51-60
- Sketch
- 软件使用
- sublime3_用户设置
- sublime下如何修改自动补全 后lang=zh-cn?
- 运营理念
- 新人指导心得体会
- 从一次活动设计,聊聊交互设计师的3个阶段
- 详情页优化那些不得不说的细节
- 店铺装修浅析
- 淘宝店铺装修之宝贝详情页的布局教程
- 宝贝详情页 客户需求调研及总结
- 宝贝描述样板房