PHP 模板引擎SMARTY 原理

1、MVC须要模板

      MVC最先是在SmallTalk语言的开发过程当中总结出的一种设计模式,MVC分别表明了"模型"、"视图"和"控制",目的就是让不一样的开发角色在大中型项目中各司其职。在网络应用程序的开发中,能够用下图来表示各概念之间的关系。
      该图展现了一个简单的WEB应用程序,用户在浏览器上看到信息是数据库服务器上的内容,但在这以前通过了应用服务器加工。开发人员负责的就是创建数据结构、处理数据的逻辑以及表示数据的方法。
      96年CGI在中国开始流行的时候,早期的WEB程序员都是从HTML开始自学成材的,在PERL中print一行行的HTML并非一件难事,可是随着网络的一步步提速,页面大小也从当初的2、三十K暴涨了十倍。写CGI程序就产生了一个迫切的要求:分开PERL和HTML源码。因而,社会进步体如今开发小组内部的分工上。因为美工和程序员对互相的工做并非十分熟悉,在进行合做的过程当中须要用一种约定的"语言"进行交流。
      这种语言并非咱们的母语或者英语,术语叫作"模板",逻辑和表示依靠它联系。它是结合了HTML和脚本语言特征的一种表达方式。经过这种方式,表示层能够按照用户所但愿的格式来显示通过逻辑层处理过的数据。若是你有Windows平台下MFC的开发经验,那么必定会很熟悉Document/Document Template/View的封装,这就是一个很典型的MVC例子。对于Web应用来讲,我的认为J2EE中的EJB/servlets/JSP是最强大的,固然还有简洁优美的Structs。另外一个颇有名的实现就是COM/DCOM+ASP,这个组合在我国是最多人使用的。
      经过几种MVC实如今WEB应用程序里的对比,能够获得一个关于模板的概念:一组插入了HTML的脚本或者说是插入了脚本HTML,经过这种插入的内容来表示变化的数据。下面给出一个模板文件的例子,这个模板通过处理后在浏览器里显示"Hello, world!"
<html>
<head>
    <title>$greetings</title>
</head>
<body>
    $greetings
<body>
</html>
       这里暂且省略处理方式,在后面作专门对比讨论。

2、为何选SMARTY?

      对PHP来讲,有不少模板引擎可供选择,好比最先的PHPLIB template和后起之秀Fast template,通过数次升级,已经至关成熟稳定。若是你对目前手中的模板引擎很满意,那么......也请往下看,相信你做为一个自由软件爱好者或者追求效率和优雅的开发者,下面的SMARTY介绍多少会有点意思。
      除了我的偏好的影响,我一直倾向于使用官方标准的实现,好比APACHE的XML引擎Axis。好处就是能够得到尽量好的兼容性(好比早期MFC对于Win3x的兼容性就比其它的应用程序框架好,固然如今各类版本都很完善了)。SMARTY发布以前我一直使用的是   PEAR  中的Integrated Template eXtension。这个引擎和PHPLIB template、Fast template几乎是兼容的,从模板的语法到对模板的处理同出一辙:都是将模板读入内存而后调用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和PHPLIB template,选PHPLIB template的缘由是在patrick的文章   《在PHP世界中选择最合适的模板》 中有一个PHPLIB template对Fast template的竞赛,结果PHPLIB template大获全胜,这使得SMARTY有了一个很好的对手。在测试以前,先谈一下在安装过程当中须要注意的问题。      

3、可能遇到的问题

      在SMARTY的   官方网站 上,有详尽的用户手册,能够选择在线HTML和PDF格式的版本。这里就再也不涉及手册上已有的内容,只是把初次使用可能遇到的问题作个解释。      
      第一个问题就很要命:提示说找不到所需文件?并非每个人都按照SMARTY默认目录结构来写应用的。这里须要手工指定,假设目录结构以下:
      就须要在index.php里指定目录结构:
$smart->template_dir = "smarty/templates/";
$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 = "/}";
       这下安装就基本完成,没问题了。  

4、反衬和类比

      先构思一下对测试的设计。主要的评比因素固然是速度了。为了进行速度测试,采起了算术平均数的做法。在测试页面中重复将页面生成N遍,再对比总页面生成时间。另外一个重要因素是易用性(至于扩展性不用比较已经有结果了),因此使用的模板不能过小。我用的是我我的主页的的页面,一个用Firework+Dreamweaver生成的HTML文件,大小约7K。其中的变量设置也采起最经常使用的区块,在PHPLIB template里叫block,而SMARTY则称section。别小看这称呼的不一样,易用性标准分两块:模板文件和脚本文件的语法是否简明易用。
            下面就深刻到测试中来。先看看两种模板文件的语法:蓝条左边是PHPLIB template的模板,右边属于SMARTY。我的偏好是不同的,因此这里不做评论。着重对比一下脚本里的处理语句,先看PHPLIB template的:
$tpl->set_file('phplib', 'bigfile.htm');
$tpl->set_block('phplib', 'row', 'rows');
for ($j = 0; $j < 10; $j++){       
    $tpl->set_var('tag' ,"$j");        
    $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发现该模板已经被编译过了,因而最耗时的一步被跳过了,而对手还要循序渐进地进行查找和替换工做。这是编译原理里讲到的很经典的"用空间换时间"例子。

5、结论

      结论就是若是你已经爱上SMARTY了,那么还等什么呢?固然并非说它就全能,就如同我用MVC模式来写个人我的网站,非但没有减小工做量,反而老是要为不一样层次间的耦合劳神。
      SMARTY不适合什么呢?举个手册里的经典例子:天气预报网站。我还想到一个:股市大盘。在这种网站上用SMARTY会因为常常的重编译而效率偏低,仍是PHPLIB template更为适合。
      本文并非为了对比两种引擎,而是为了说明SMARTY的优点。使用它最有意义之处在于它是PHP新体系的一部份,做为一支独立的力量,除了.NET和JAVA ONE这两大致系以外,大中型web开发还有别的选择。这对于GNU项目来讲,其意义无异于刘邓大军千里跃进大别山。
相关文章
相关标签/搜索