[翻译] 简单的PHP模板引擎
PHP 相当于模板?
PHP 是一种有点罕见的语言,因为它不需要额外修改或库的支持,就已经在标记中实现将文本模板化。这很可能是如今 PHP 成为最流行的 WEB 编程语言一员的重要促成因素之一(不能是唯一因素,因为它对 ColdFusion 不起作用)。大多数其它 WEB 编程语言拥有一种或多种具有不同语法的模板语言,这种语法需要在实现语言基础上进行学习。PHP 降低了进入门槛,允许你将 PHP 代码直接放进 HTML。
但是众所周知,在你 PHP 之旅的某个时刻,你将会意识到需要分离表示逻辑和应用逻辑。有些开发者开始使用其它提供不同语法的解决方案。我有点儿困惑于为何这似乎成了常见做法,PHP 能够提供相同的功能,不用在 PHP 已经做到的基础上增添另一种模板语法。你仍能够通过简单的类实现分离需求(文章末尾会展示)。
我主要见到人们趋向于在 PHP 之上使用两种解决方案。一种解决方案是在 PHP 基础上使用预制模板引擎,如 Smarty。另一种是在模板文件中使用字符串替换技术。
字符串替换……很差劲
如果你编写自己的模板引擎,最有可能使用 srt_replace
或 preg_replace
实现代码动态部分的嵌入。这样做有两个问题:一是它很慢;二是它难以实现提供健壮模板语言所需要的所有功能。类似格式化函数、控制结构等添加到这种方案中有点儿蹩脚。另一个选项是实现非常简单的变量替换,然后执行格式化函数、控制结构等。在你的控制器中,只是把结果分配给变量替换,但是,那完全违反了使用模板引擎的意义。当你在模板之外执行一些表示逻辑时,表示逻辑和应用逻辑的分离会变得非常模糊。
我是不是提到过这是一个非常慢的解决方案?
Smarty 及其它模板引擎
Smarty 和类似的模板引擎非常多余的。这里有一个 Sarty 工作流的示例:
- Smarty 语言被解析
- 被 PHP 编译
- PHP 代码被换成
- PHP 代码被解析
- PHP 代码被编译到 Opcodes
- 如果你有 Opcode 缓存,Opcode 被缓存
- Opcode 运行
如果你没有看出多余的地方,是我做的不是很好。Smarty 的整个概念就像在一辆车的基础上再加一辆车,并且相信它能提高你的汽油里程。很多人抱怨 Smarty 语法在模板方面比 PHP 更好。胡扯。Smarty 的语法没有任何真正增益,它只是看起来比较简洁,但是实际上从它身上得到的好处并不值得让 PHP 更加臃肿。你节省了几次按键的敲击,真了不起。{$var}
对比 <?=$var?>
。如果我能感受到优化,那也是微不足道的。PHP 结构控制和格式化比 Smarty 的更加简洁和清晰,Smarty 在大多数 IDE 中不被支持,而使用 PHP 你可以获得所有 IDE(或编辑器)带给你的一切,如代码自动完成、高亮显示、语法验证等。
常见(蹩脚)的借口
我的设计师们不懂 PHP
他们也不懂你为他们挑选的模板语言。如果他们打算学习一些东西的话,让他们学习足够的 PHP 再去设计他们的模板。像 Smarty 这样的语法根本不容易学习。
我不能用 PHP!因为不能分离表示逻辑!
实际上你能做到清晰的分离。请看下方的类代码。
PHP 用于模板的语法糟糕透了
不,它刚刚好,真的。
我不相信我的设计师们使用 PHP
你正在用模板引擎解决错误的问题。模板引擎意味着通过逻辑的分离实现更高级可维护性。你所尝试解决的是你工作文化中的缺陷。如今,设计师们不需要编写糟糕的服务端代码去导致很多小问题,他们能够编写一些同样糟糕可怕的客户端代码。此外,你的模板引擎应该是灵活的,免得你在实现中碰壁。你不希望,因为你没有做代码审查(如果你真的不相信你的设计师们,只需要让他们制作一些静态 HTML 样板,让一名处级开发者将它们变成模板)。
我不喜欢 PHP
我也是,这是为什么我使用 Java 和 JSP。
代码
用法:
main.php 模板:
content.php:
controller.php:
你可能想要查看的其它 PHP 模板解决方案
编辑 添加了检查以确保没有人尝试绑定名为 view_template_file
的变量去防止某人做某些蠢事,并将整个请求绑定到覆盖该变量的函数。导致严重的漏洞。