深入浅出之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
深入浅出之Smarty模板引擎工作机制(二)的更多相关文章
- 深入浅出之Smarty模板引擎工作机制(一)
深入浅出Smarty模板引擎工作机制,我们将对比使用smarty模板引擎和没使用smarty模板引擎的两种开发方式的区别,并动手开发一个自己的模板引擎,以便加深对smarty模板引擎工作机制的理解. ...
- smarty模板引擎基础(二)
smarty模板引擎所需文件夹共可分为存放页面缓存的(cache).存放配置文件的(configs).存放模板扩充插件的(plugins).存放模板文件的(templates).存放编译后的模板文件的 ...
- Smarty模板引擎技术二
Smarty模板引擎技术 内建函数 include_php内建函数 作用:载入一个php文件,将载入的文件的内容赋值给一个变量 注意:该内建函数只能在2.0中使用,如果使用的话,必须得实例化Sma ...
- 写一个迷你版Smarty模板引擎,对认识模板引擎原理非常好(附代码)
前些时间在看创智博客韩顺平的Smarty模板引擎教程,再结合自己跟李炎恢第二季开发中CMS系统写的tpl模板引擎.今天就写一个迷你版的Smarty引擎,虽然说我并没有深入分析过Smarty的源码,但是 ...
- Smarty模板引擎技术
Smarty模板引擎技术 什么是模板引擎? 什么是Smarty模板引擎? 为何选择Smarty模板引擎? 如何使用Smarty模板引擎? 一.历史背景 场景一:回顾之前编写PHP项目的方式 //链接数 ...
- 浅谈dedecms模板引擎工作原理及其自定义标签
浅谈dedecms模板引擎工作原理: 理解织梦模板引擎有什么意思? 可以更好地自定义标签.更多在于了解织梦系统,理解模板引擎是理解织梦工作原理的第一步. 理解织梦会使我们写PHP代码是更顺手,同时能学 ...
- smarty模板引擎(一)基础知识
一.基本概念 1.什么是mvc? mvc是一种开发模式,核心思想是:数据的输入.数据的处理.数据显示的强制分离. 2.什么是smarty? smarty是一个php的模板引擎.更明白的 ...
- MVC开发模式以及Smarty模板引擎的使用
Linux 全局安装 composer 将目录切换到/usr/local/bin/目录 cd /usr/local/bin/ 在 bin 目录中下载 composer curl -sS https:/ ...
- smarty模板引擎
1. 使用smarty 1.1 项目引入 // 3, 连接数据库,提取相关数据 $title = "Smarty模板引擎"; $content = "Smarty模 ...
随机推荐
- Delphi反汇编内部字符串处理函数/过程不完全列表
Delphi反汇编内部字符串处理函数/过程不完全列表 名称 参数 返回值 作用 等价形式 / 备注 _PStrCat EAX :目标字符串 EDX :源字符串 EAX 连接两个 Pascal 字符 ...
- windows远程连接linux桌面---使用tightvnc或者tigervnc
一.安装tightvnc: tightvnc的安装在安装包中有详细的说明(README文件) 首先你要确保linux已经安装jpeg和zlib库, 2.编译 执行如下两个命令: [root@local ...
- ISAPI在IIS7上的配置
主要介绍ISAPI的作用.ISAPI在IIS7上的配置.开发ISAPI的基本内容及使用VS 2008配置ISAPI DLL开发项目. 一.ISAPI介绍 缩写词=Internet Server App ...
- 【剑指offer 面试题12】打印1到最大的n位数
思路: 用n位字符数组表示n位数,通过递归的方式逐层(位)遍历,递归终止时打印. #include "stdio.h" #include "string.h" ...
- Java进程占用CPU资源过多分析
问题描述: 生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高. 问题分析: 1,程序属于CPU密集型,和开发沟通 ...
- C#几种截取字符串的方法小结
1.根据单个分隔字符用split截取例如代码如下: string st="GT123_1"; string[] sArray=st.split("_"); 即可 ...
- Python 核心数据类型
1.Python中一切皆对象 2.Python中不需要申明对象类型,对象的类型由运行的表达式决定 3.创建了对象意味着绑定了对象的操作到此对象,也就是在固有的对象上只能调用该对象特有的操作.比如只能将 ...
- 判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence
// 判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence // 题意:三种操作,1增加值,2开根,3求和 // 思路:这题与HDU 4027 和HDU 5634 ...
- linux内核地址mapping
linux内核采用页式存储管理,虚拟地址空间划分成固定大小的页面,由MMU(memory manager unit)在运行时将virtual address mapping to (或者说是变化成)某 ...
- ColorNote[动态][log]
Windows 应用商店上传日志 [ColorNote In Windows APP Store Log]: ColorNote v1.0 2012/12/2 ColorNote v1.1 2012/ ...