|
模板引擎的概念如何?ThinkTemplate模板引擎的设计原理是怎样的?如何设计和实现一个性能卓越的模板引擎?
在PHP开发的过程中,我们会接触到很多的模板引擎,包括FastTemplate、SmartTemplate、Smarty、tinybutstrong等,通常都是为了满足MVC开发模式的表现层需要,让显示和逻辑可以更好的分离(当然,现在的模板引擎越做越强大,甚至开始介入“M”)。
有了模板引擎,开发者可以专注于程序代码,设计者可以专注于页面的布局和视觉效果,不必再担心要在模板中嵌入各种程序代码。模板引擎的运作过程如下页图1所示。
ThinkTemplate是一个使用了XML标签库技术的编译型模板引擎,支持两种类型的模板标签,使用动态编译和缓存技术,而且支持自定义标签库。ThinkTemplate作为ThinkPHP框架的一个模板引擎插件提供,也可独立使用,因为ThinkPHP本身的设计是可以灵活替换模板引擎的。
ThinkTemplate的使用方法非常简单,直接创建ThinkTemplate对象后进行模板变量赋值然后进行渲染输出就可实现,然后就是定义模板标签和输出变量,和Smarty的用法比较类似。
而Smarty在渲染模板的时候必须指定模板文件名,在ThinkTemplate中如果不指定模板文件名,会按照系统设置的规则进行自动定位,例如,当前模块的某个操作可以定位成为以模块名称为目录下面的一个操作命名的模板文件。
在进行模板变量赋值的时候,可以对任何变量进行赋值,由模板标签来决定输出何种类型的。并且,赋值具有智能化和批量赋值,默认情况下第一个参数是要在模板中输出的变量名称,而第二个参数是变量的值,但是如果没有指定第二个参数,那么会对第一个参数进行判断,如果是索引数组,则自动进行批量赋值。作为安全性考虑,没有赋值的模板变量是不能用于输出的,但是有些特殊的模板标签可以输出系统的常量和系统变量例外。
评判模板引擎的优劣,并不仅仅在于外表看来的使用方式,更关键的在于内在的功能和效率。通常,模板引擎主要考虑以下几个方面:
◆ 执行速度
◆ 标签功能
◆ 扩展功能
执行速度是其中最关键的因素,毕竟这是应用的前提。一个模板引擎再好用,但是每次执行都需要几秒的话,那恐怕也无人问津。通常,我们会更加倾向于选择简洁快速的模板引擎,哪怕功能并不是那么强大(简洁不等于功能不足)。
要准确判断执行速度首先要了解解释型模板引擎和编译型模板引擎的区别。
所谓解释型就是每次将模板内容读入内存,并通过正则等方式分析字符串后对预置的标签进行替换,每次加载模板都需要重复这个过程。而编译型模板引擎是在第一次执行模板文件的时候进行一次编译(相当于一次解释分析过程),然后生成一个编译后的缓存文件,下次执行的时候就可以直接执行缓存文件,无需再次编译。
因此,在速度上面,编译型模板引擎在第一次运行模板的时候,速度会比解释型模板引擎略微缓慢,是因为有严格的编译(包括生成缓存文件)过程,这个过程根据模板引擎的复杂程度和模板页面标签多少速度有所不同。而当第二次执行的时候,因为最耗时的过程已经跳过了,编译型模板引擎的优势就体现出来了。这也是编译原理中所谓的“空间换时间”例证。
目前大多数的模板引擎都采用编译型,但是是否为编译型和模板功能并没有直接关系。ThinkTemplate属于编译型模板引擎,具备动态生成缓存文件的能力,无论是模板文件修改或者是缓存文件被删除,系统都会重新生成缓存文件。同时还可以设置模板缓存的有效时间,如每隔10分钟重新编译模板文件。并且在编译模板文件的过程中,如果发现存在很多相同的标签,ThinkTemplate并不会重复解析,而是会读取解析缓存。因此,无论在解析还是执行上面,效率都是比较高的。
模板引擎的一个重要因素就是模板标签的功能。Smarty模板引擎以功能最强大而著称,标签的易用性和完善性也是模板引擎的关键因素之一,最基本的功能包括注释、变量输出、条件控制、包含文件,而这些功能的体现都是借助于一系列的模板标签。这一部分是设计模板引擎的关键,也是工作量比较大的地方。
目前见到的模板引擎标签,大致分为特定标签和XML标签两种类型。特定标签通常是比较常见的类型,由模板引擎自身定义的一系列标签,用来满足变量输出和控制需要,通常具有私有化规则,标签类型各不相同。当然有些模板引擎是设计为可以定义起始标签的。
除了输出模板变量之外,模板引擎通常都会提供一个特殊的标签输出方式用来输出一些常量和系统变量。
和其他的模板引擎不同,ThinkTemplate的特定标签仅仅是用于变量输出功能,而把控制功能和复杂的标签功能放到XML模板标签里面。XML模板引擎在Java领域里面是非常常见的,在PHP模板引擎领域似乎并不多见,但是ThinkTemplate在实现自身的特定标签外,还有效地借鉴了Java的标签库技术,实现了XML模板标签支持,并且允许自定义标签库。两种标签方式的结合使用,可以让模板定义更加灵活,这也正是ThinkTemplate模板引擎的特色。
基于某些兼容性考虑,通常在模板文件中可以直接插入php代码,用来完成模板标签所无法完成,或者比较困难的功能。这种方式与标签的互补可以满足绝大多数的模板需要。事实上,我在用其他模板引擎的时候,都会经常在模板文件中直接添加一些个别的php代码来辅助。需要注意的是并不是所有的模板引擎都支持在模板中直接写php代码。
任何一个模板引擎的功能,都不是为你量身定制的,具有一个良好的可扩展机制也是模板引擎的另外一个考量。Smarty采用的是插件方法来实现扩展,ThinkTemplate由于采用了标签库技术,比Smarty提供了更为强大的定制功能,和Java的TagLibs一样可以支持自定义标签库和标签,每个XML标签都有独立的解析方法,所以,可以根据标签库的定义规则来增加和修改标签解析规则。在ThinkTemplate中标签库的提现是采用XML命名空间的方式。
每个命名空间都有一个对应的标签库XML定义文件,并且还包含有一个用于解析该标签库的类文件。系统默认对cx标签库进行支持,所以在定义cx标签库标签时候,可以省略XML的命名空间前缀。
当系统中存在很多的标签库的时候,每次编译都会加载所有的标签库解析文件,这样会造成一种浪费,因为很多情况,我们可能只是使用其中的一个或者二个标签库。所以,我们还必须在模板页面实现标签库引入功能,来告诉模板引擎当前模板页面需要哪些标签库的支持,从而加载需要的解析类。在ThinkTemplate中,使用tagLib标签来实现这一功能。
利用标签库的特性,我们可以非常方便地扩展自己需要的标签,ThinkTemplate正是采用这种机制来内置集成了一些常用的HTML组件标签。使用特定的自定义XML标签定义了一个DataGrid组件,省去了复杂的Html代码,在模板第一次执行的时候,模板引擎会把上面的组件标签解析成PHP和Html结合的代码,生成缓存文件。
一个性能卓越的模板引擎设计,还要在很多细节方面。例如优化解析效率、包含机制、安全考虑、特殊变量解析、异常处理等,只有各方面协调好才能更好地发挥作用。
图1 模板引擎的运作过程
链 接
ThinkPHP是一个开源的快速、兼容而且简单的面向对象的轻量级PHP开发框架,ThinkPHP框架致力于简化企业级应用开发过程。ThinkPHP从Java的Struts结构移植过来,使用面向对象的开发结构和MVC模式,并且模拟实现了Struts的标签库,借鉴了国外一些不错的思想,尤其是Java框架方面,因此熟悉J2EE的开发人员相对比较容易上手,其模版引擎、缓存机制、认证机制和扩展性方面均表现不凡。在对数据库的支持方面已经包括MySQL、MSSQL、Sqlite、PgSQL、Oracle,以及PDO的支持,让开发人员有更多选择。
链 接
ThinkPHP主要有以下特性:
◆ 兼容PHP4和PHP5
◆ 单一入口模式,跨平台
◆ 内置模版引擎,支持标签库
◆ 内建多元化缓存机制
◆ 完善的AJAX支持
◆ 抽象数据库访问层和PDO支持
◆ 提供CURD和ORM
◆ 自动生成、表单验证支持
◆ 具备许多ROR特性
◆ 插件支持和可扩展能力
◆ 多语言和多模版支持
◆ 集成RBAC权限控制
|