详解 PHP 之 Smarty
——————如何实现代码与页面的分离 在任何 Web 应用中,如何将程序代码和界面设计,或者说,将逻辑层和表现层分离开 来,都会是一个问题。对于 PHP 这种类型的嵌入网页的脚本语言,这一问题尤其突出。在 新手编写的代码中,把访问数据库的代码和操纵 HTML 元素的代码写在同一个页面里,是 很常见的情况。 为了避免这一问题, 开发者倾向于将涉及业务逻辑的代码封装在某些单独的 库文件中,再在负责显示界面的文件中将它们 include 进来。但是,这仍然无法避免在显示 界面的文件中包含大量的 PHP 代码。究其所以然,是因为除了涉及业务逻辑的代码以外, 即使仅仅在显示层,也往往涉及到复杂的显示逻辑。在一个典型的显示页面中,程序需要先 包含所有必需的库文件,初始化上下文环境,创建相关业务逻辑对象(假如数据库访问代码 已经被业务逻辑对象封装,可以节省数据库相关的代码) ,最后在 HTML 的空隙中把对象格 式化为 HTML 元素进行显示。 于是我们看到了无数这样的页面, 在第一行 HTML 开始之前, 就已经包含了数十行甚至更多的 PHP 代码,在 HTML 的内部,仍然充满了各种各样的 PHP 代码。因此,PHP 代码和 HTML 代码搅和在一块的问题仍然无法解决,对 HTML 的修改仍 然可能导致整个 PHP
程序崩溃。更加麻烦的是,这种不清晰的结构妨碍了 PHP 应用在规模 上的进一步扩张。 为了解决这一
问题,模板(template)技术应运而生。模板技术的基本原理是,通过一 个解析器(parser) ,读取指定的模板文件(包含了某些特定标签的 HTML 文件) ,将这些标 签替换为相关的 PHP 变量,再输出为标准的
HTML。通过这种方式,不但分离了业务逻辑 层和表现层,而且也尽可能地分离了显示逻辑和 HTML 代码。通过替换不同的模板文件, 可以方便地生成各种格式的输出,例如 HTML,XML,WML,后期稍加处理甚至可以生成 PDF 和 Flash。早期较为著名的 PHP 模板引擎有 PHPLib 中的 Template 和 FastTemplate。 但是,模板技术也有其先天的缺陷。 无法彻底分离逻辑。显示逻辑和 HTML 代码很难通过简单的标签替换,实现彻底的分 离。例如,遍历并显示一个数组,在 PHP 中可以用简单的 foreach 语句实现,但是使用模板 时,就需要进行对整个模板文件进行多次替换操作,造成效率的极大降低;或者根据不同的 数据值显示不同的格式,如果模板文件完全不包含 PHP 代码,那么将很难做到这一点。 解析导致的性能损失。由于每次 PHP 页面被访问时,解析器都必须对模板文件进行替 换操作,无疑会降低 PHP 应用的性能。尤其在多次的替换操作时更是如
此。因此,不使用 模板比使用模板往往更加快速,这也是许多 PHP 程序员摒弃模板技术的原因之一。 在经过数年的发展之后,“编译型”的模板技术渐渐占据了主流。所谓“编译型”,是指解 析器读取模板文件以后,并不直接生成静态 HTML,而是“编译”成一个新的 PHP 文件,并 将它保存起来。以后访问该页面时,模板引擎会直接执行“编译”后的 PHP 文件。Smarty 是 这种模板引擎的代表。 针对以上的两个问题,Smarty 作了如下处理: 独立语法。Smarty 实现了一套自己的语法,这套语法不但支持变量替换和简单的判断, 而且支持循环,修饰符(modifier) ,内置了很多功能强大的函数,而且还支持自定义函数。 这套系统保证 Smarty 能够完全独立地处理显示输出,无须再和
PHP 有什么瓜葛。事实上,
在 Smarty 模板中,是不可以直接使用 PHP 代码的(通过显式定义可以使用) ,这也是一种 强制分离逻辑层和表现层的方式。 (理论上来说, Smarty 的模板文件也可以应用于其它语言。 ) 但是,这种解决方式也受到了指责,因为 Smarty 的语法过于强大,几乎变成了一门新的语 言,指责者认为,这反而增加了复杂性。但是,