(PHP)模板引擎Smarty介绍
模板 引擎smarty深入浅出介绍——php
来自
: cjjer 做了部分变动
用php实现mvc开发模式的逻辑层和表示层有多种模板引擎可供选择,但是官方引擎smarty诞生后,选择就有了变化。它的理念和实现都是相当前卫的。本文主要讨论smarty之于其他模板引擎的不同特点,简要介绍了该引擎的安装及使用,并用一个小的测试案例对比了smarty和phplibtemplate的速度和易用性。
一、mvc需要模板
mvc最早是在smalltalk语言的开发过程中总结出的一种设计模式,mvc分别代表了模型、视图和控制,目的就是让不同的开发角色在大中型项目中各司其职。在网络应用程序的开发中,可以用下图来表示各概念之间的关系。
该图展示了一个简单的web应用程序,用户在浏览器上看到信息是数据库服务器上的内容,但在这之前经过了应用服务器加工。开发人员负责的就是建立数据结构、处理数据的逻辑以及表示数据的方法。
96年cgi在中国开始流行的时候,早期的web程序员都是从html开始自学成材的,在perl中print一行行的html并不是一件难事,但是随着网络的一步步提速,页面大小也从当初的二、三十k暴涨了十倍。写cgi程序就产生了一个迫切的要求:分开perl和html源码。于是,社会进步体现在开发小组内部的分工上。由于美工和程序员对互相的工作并不是十分熟悉,在进行合作的过程中需要用一种约定的语言进行交流。
这种语言并不是我们的母语或者英语,术语叫做模板,逻辑和表示依靠它联系。它是结合了html和脚本语言特征的一种表达方式。通过这种方式,表示层可以按照用户所希望的格式来显示经过逻辑层处理过的数据。如果你有windows平台下mfc的开发经验,那么一定会很熟悉document/documenttemplate/view的封装,这就是一个很典型的mvc例子。对于web应用来说,个人认为j2ee中的ejb/servlets/jsp是最强大的,当然还有简洁优美的structs。另一个很有名的实现就是com/dcom+asp,这个组合在我国是最多人使用的。
通过几种mvc实现在web应用程序里的对比,可以得到一个关于模板的概念:一组插入了html的脚本或者说是插入了脚本html,通过这种插入的内容来表示变化的数据。下面给出一个模板文件的例子,这个模板经过处理后在浏览器里显示hello,world!
$greetings
这里暂且省略处理方式,在后面做专门对比讨论。
二、为什么选smarty?
对php来说,有很多模板引擎可供选择,比如最早的phplibtemplate和后起之秀fasttemplate,经过数次升级,已经相当成熟稳定。如果你对目前手中的模板引擎很满意,那么......也请往下看,相信你作为一个自由软件爱好者或者追求效率和优雅的开发者,下面的smarty介绍多少会有点意思。
除了个人偏好的影响,我一直倾向于使用官方标准的实现,比如apache的xml引擎axis。好处就是可以获得尽可能好的兼容性(比如早期mfc对于win3x的兼容性就比其它的应用程序框架好,当然现在各种版本都很完善了)。smarty发布之前我一直使用的是pear中的integrated template extension。这个引擎和phplibtemplate、fasttemplate几乎是兼容的,从模板的语法到对模板的处理同出一辙:都是将模板读入内存然后调用parse()函数,用数据对预置的标记进行替换。
下面看看smarty是怎么做的。接到request后,先判断是否第一次请求该url,如果是,将该url所需的模板文件编译成php脚本,然后redirect;如果不是,就是说该url的模板已经被编译过了,检查不需要重编译后可以马上redirect,重编译条件可以自己设定为固定时限,默认的是模板文件被修改。
怎么样,看起来是不是有点眼熟?想起来了──这不就是jsp的原理嘛!的确,这种编译用在php这样的解释性脚本引擎上显得匪夷所思,但是仔细想想,java不也是由jvm解释执行的吗?这就叫没有做不到,只有想不到。
既然谈到了java,就再对php的未来发表一点看法。php官方网站上宣布了要在2003年年底发布php5.0版。这个版本拥有很多崭新的特性:比如异常处理,命名空间,更加面向对象等等。可以说越来越向java靠拢,smarty也是新特性之一,使得php更适用于大中型项目的开发。但是似乎离我当初选择它的原因──灵巧易用──越来越远了。但就一个软件的生存周期来看,php正处在成长期,开发者赋予它更多的功能,以期能胜任商业应用是利大于弊的。作为php的忠实用户,肯定不希望php总是被人指责能力不足吧?
为什么选择smarty,仅仅因为它很像jsp?当然有更为充分的理由。首先,除了第一次编译的成本比较高之外,只要不修改模板文件,编译好的cache脚本就随时可用,省去了大量的parse()时间;其次smarty像php一样有丰富的函数库,从统计字数到自动缩进、文字环绕以及正则表达式都可以直接使用;如果觉得不够,比如需要数据结果集分页显示的功能,smarty还有很强的扩展能力,可以通过插件的形式进行扩充。
事实胜于雄辩。我设计了一个测试程序,通过速度和开发难度这两个因素对比了一下smarty和phplibtemplate,选phplibtemplate的原因是在patrick的文章《在php世界中选择最合适的模板》中有一个phplib template对fasttemplate的竞赛,结果phplibtemplate大获全胜,这使得smarty有了一个很好的对手。在测试之前,先谈一下在安装过程中需要注意的问题。
三、可能遇到的问题
在smarty的 官方网站上,有详尽的用户手册,可以选择在线html和pdf格式的版本。这里就不再涉及手册上已有的内容,只是把初次使用可能遇到的问题做个解释。
$smart->compile_dir = "smarty/templates_c/";
$smart->config_dir = "smarty/configs/";
$smart->cache_dir = "smarty/cache/";
第一个问题解决了,紧接着就是第二个:我刚用dreamweaver生成的漂亮模板怎么不能用?并不是模板文件有什么问题,而是因为smarty默认的标记分隔符是{},不巧的是javascript肯定包含这个标记。好在我们可以用任意字符当作分隔符,再加上这两句:
$smart->left_delimiter = "{/";
$smart->right_delimiter = "/}";
这下安装就基本完成,没问题了。
四、反衬和类比
先构思一下对测试的设计。主要的评比因素当然是速度了。为了进行速度测试,采取了算术平均数的作法。在测试页面中重复将页面生成n遍,再对比总页面生成时间。另一个重要因素是易用性(至于扩展性不用比较已经有结果了),所以使用的模板不能太小。我用的是我个人主页的的页面,一个用firework+dreamweaver生成的html文件,大小约7k。其中的变量设置也采取最常用的区块,在phplib template里叫block,而smarty则称section。别小看这称呼的不同,易用性标准分两块:模板文件和脚本文件的语法是否简明易用。
$tpl->parse(rows, row, true);
}
$tpl->parse(out, phplib);
$tpl->p(out);
下面是smarty的:
$smart->assign(row,$row);
$smart->display(bigfile.htm);
smarty只用了tags和row两个变量,而phplib template则多了模板文件的handler,还有一个莫名其妙的out。说实在的这个out我当初学的时候就不知道为什么要存在,现在看起来,还是别扭。为什么smarty少那么多处理语句呢?答案是工作由引擎完成了。如果你喜欢钻研源程序,可以发现在smarty_compiler.class.php里有一个名叫_compile_tag()的函数,由它负责把section这个标签转换成php语句。这不是一个普通的标签,它带有参数和数据,节省了脚本编程的工作量,而模板标签上的工作量相差又不大,可以判定在易用性上smarty高出一畴。
下面该轮到我们最关注的速度了,毕竟对于一个熟练的web开发者来说,掌握再困难的工具不过是时间问题,何况模板引擎这种学习曲线平缓的技术。而速度则是web应用程序的生命,尤其是模板引擎使用在并发访问量很大的站点上,这点就更重要了。测试开始前,我觉得phplib template会在这一环节上胜出,因为它经历了很多次升级,已经基本没有什么bug,而且smarty的引擎个头太大,不像它的对手只有两个文件。
果然,测试结果如下图,phplib template有25%的速度优势:

phplib基本没变化,但是smarty提高了25%的速度。继续刷新,得到的都是类似于第二次的结果:smarty比phplib template 快上近10%。我想这就是编译型比解释型快的原理了。smarty引擎本身就很大,加上还要把模板编译成php文件,速度当然比不上小巧的phplib template。但这只是第一次的情况。第二次接到请求的时候,smarty发现该模板已经被编译过了,于是最耗时的一步被跳过了,而对手还要按部就班地进行查找和替换工作。这是编译原理里讲到的很经典的"用空间换时间"例子。
五、结论
结论就是如果你已经爱上smarty了,那么还等什么呢?当然并不是说它就全能,就如同我用mvc模式来写我的个人网站,非但没有减少工作量,反而总是要为不同层次间的耦合劳神。
smarty不适合什么呢?举个手册里的经典例子:天气预报网站。我还想到一个:股市大盘。在这种网站上用smarty会由于经常的重编译而效率偏低,还是phplib template更为适合。
本文并不是为了对比两种引擎,而是为了说明smarty的优势。使用它最有意义之处在于它是php新体系的一部份,作为一支独立的力量,除了.net和java one这两大体系之外,大中型web开发还有别的选择。这对于gnu项目来说,其意义无异于刘邓大军千里跃进大别山。
作者:于博翔
- · 用PHP操纵Oracle的LOB类型的数据
- · C# 2.0中泛型编程初级入门教程
- · asp.net 2.0中加密web.config
- · ADO.NET操纵数据库
- · 关于asp.net c#中对cookie的操作
- · asp.net 2.0里当readonly遇上enableviewstate=false
- · C# 2.0与泛型
- · 让3721也无奈的弹出窗口(代码)
- · 玩透9种网页弹出窗口(精)
- · 网站左右两边浮动广告JS代码
- · 一个IP只提示一次设为首页的代码
- · 常用ASP脚本程序集锦*精(适合初学者)
- · 鼠标自动移动/点击
- · PHP程序加速探索之加速工具软件
- · SQLServer2000数据访问基类
- · 图解MySQL数据库的安装和操作
- · 一些ASP初学者常用的代码
- · ASP经典问答收藏之一
- · 一段防注入的通用脚本
- · 简单的防盗链(代码)
- · PHP窜红:革命尚未成功 Java仍需努力
- · 使用PHP编写基于Web的文件管理系统
- · 理解PHP中的MVC编程之控制器
- · 理解PHP中的MVC编程之MVC框架简介
- · SQL Server Express 数据库自动部署问题及解决
- · 用PHP文件上传的具体思路及实现
- · 回顾与展望PHP 5.0的变化与PHP 6.0展望
- · 一个产生中文累计数的代码片断
- · 在SQL Server 2005中解决死锁
- · 30分钟正则表达式指导
- · 不算不知道 44% 数据库开发者使用MySQL
- · 立即释放.net下的com组件
- · XHTML的目标,规则和细节
- · SQL Server 2005 提供的分页查询支持
- · ASP.NET程序中常用的三十三种代码
- · Sql server存储过程和C#分页类简化你的代码
- · SQL Server 2005新功能-TSQL
- · 在SQL Server 2005中编辑SQL Server 2000 DTS
- · .NET 连接到 Oracle的oci.dll加载错误解决方案
- · 如何在调用线程的时候传递参数
- · 专家预言:PHP将比Java更好更受欢迎
- · 在IIS6.0下ASP .NET 的版本冲突问题
- · 解决SqlTransaction用尽的问题(SQL处理超时)
- · 以前编写Like谓词被忽略的使用方法
- · 在编写存储过程时使用 Set NoCount On
- · ASP.NET 2.0运行时简要分析
- · .Net中如何操作IIS(原理篇)
- · 用.net开发不同操作系统下应用的winform的size大小问题
- · SQL Server数据库文件恢复技术
- · SQL SERVER中一些常见性能问题的总结
- · .NET下对二进制文件进行加密解密(C#)
- · 利用.NET的File控件上传文件的最终解决方案(个人版)
- · 如何把图片、声音等存储到sql中
- · MS-SQL server数据库开发精典技巧
- · 全文索引—CONTAINS语法
- · 获得所有表信息的SQL语句
- · .NET扫描远程计算机注册表
- · 利用JS获取IE客户端IP及MAC的实现
- · 简单而又复杂的ASP.NET编程模型
- · C#2.0终于有了?:便捷判断的单分支版

