【问题标题】:What are the real advantages of templating engines over just using PHP?与仅使用 PHP 相比,模板引擎的真正优势是什么?
【发布时间】:2011-01-21 00:51:27
【问题描述】:

我只为视图文件使用 PHP 来开发我的 Web 应用程序,我不觉得有任何限制,但我听说有一致数量的开发人员提倡“外部”模板引擎。那么模板引擎提供了哪些简单的 PHP 所缺乏的功能呢?

我在寻找实用的东西,所以我排除了以下内容:

  • 照看糟糕的开发人员(即使用模板引擎,因为它迫使您不要将代码混入演示文稿中)
  • 语法简洁(我在 Vim 中有 <?php echo $stuff; ?> 之类的映射,使用花括号不会有任何区别)
  • 为非程序员提供更简单的语法(我独自开发,所以这不是问题)

【问题讨论】:

    标签: php templates template-engine


    【解决方案1】:

    新语法


    有些人不会同意,但因为我一直在使用 Twig,所以“for ... else”感觉不错。它可能不是很多,但它使我的模板更清晰。

    {% for row in articles %}
     Display articles ...
    {% else %}
     No articles.
    {% endfor %}
    

    自动转义


    您可以让模板引擎自动转义任何输出。这很棒,因为您不再需要在任何地方重复 htmlspecialchars ...。 Twig 做得很好。

    {% autoescape on %}
      Everything will be automatically escaped in this block
    {% endautoescape %}
    

    模板继承


    我喜欢的另一个功能是扩展基本模板的能力。这是一个基本的例子

    base.html 模板

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
    <html lang="en">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
      {% block head %}
        <link rel="stylesheet" href="style.css" />
        <title>{% block title %}{% endblock %} - My Webpage</title>
      {% endblock %}
    </head>
    <body>
      <div id="content">{% block content %}{% endblock %}</div>
      <div id="footer">
        {% block footer %}
          &copy; Copyright 2009 by <a href="http://domain.invalid/">you</a>.
        {% endblock %}
      </div>
    </body>
    

    child.html 模板

    {% extends "base.html" %}
    
    {% block title %}Index{% endblock %}
    {% block head %}
      {% parent %}
      <style type="text/css">
        .important { color: #336699; }
      </style>
    {% endblock %}
    {% block content %}
      <h1>Index</h1>
      <p class="important">
        Welcome on my awesome homepage.
      </p>
    {% endblock %}
    

    子模板可以覆盖页面特定样式、内容等的块...您还可以注意到 {% parent %} 的使用,它抓取父内容,因此您在覆盖时不会丢失所有内容。

    我建议您试一试Twig。非常有用。

    【讨论】:

    • 只有我一个人,还是像 Django 模板很多
    • 可能吧,我得看看 Fabien 怎么说。
    • 我觉得它很像 Jinja 模板。
    • +1 在 for 循环中 这在 PHP 中看起来非常可怕,并且完全破坏了可读性。此外,到处都是 PHP 的开始和结束标记破坏了 HTML 语法的美观。
    【解决方案2】:

    关注点分离。

    当使用 MVC/MTV 方法时,这类事情是标准的 - 其中数据的表示必须与数据的显示分开,但如果您使用的是普通的 PHP,则不是。

    使用模板引擎可以轻松地将显示的内容与显示的方式区分开来。

    我想你可能会争辩说,这属于“照顾糟糕的开发人员”,因为无论如何优秀的开发人员都应该这样做,但在我看来,模板引擎也让优秀的开发人员更容易。

    【讨论】:

    • 这对我来说听起来像是婴儿坐姿的争论。
    • 关注点分离在各个层面都是好事;但这并不一定意味着将每个“关注”放在不同的文件中。仅当您有不同的团队从事设计和逻辑工作时,这一点才重要。
    • @EvilRyry:这更多是关于工程而不是保姆。代码的东西,模板显示的东西。两者是分开的,不相关的。一个人应该能够在不改变行为的情况下改变外观。真正优秀的 PHP 程序员或许能够做到这一点,但模板引擎让这件事变得更容易,因为您不再需要费心处理细节——只需将数据交给模板引擎。
    • @EvilRyry - 完全同意@S.Lott 所说的。我认为自己是一个相当称职的开发人员,但除非架构强制执行良好的习惯(例如将数据的显示与数据的获取分开),否则我会变得懒惰,并将两者混为一谈。换句话说,我有一个需要照看孩子。
    • @Javier - 这不是完全必要的,但它确实很有帮助。
    【解决方案3】:

    在视图之间轻松切换

    以网络的当前状态,我需要以不同的格式提供我的信息:

    • 静态 html 页面
    • 另一个 HTML 页面上的动态加载视图
    • 数据的 JSON 对象
    • 数据的 XML 提要,在我的 flash 部分中使用

    这些格式的信息可以相同,只是视图不同。使用某种模板引擎,我可以在这些视图之间快速切换。

    【讨论】:

    • +1 - 想想 PC 版和移动版。这也使您可以更轻松地为假期或特殊销售设置不同的页面样式。
    • 同意“使用某种模板引擎”,没有回答为什么使用外部引擎而不是 PHP。
    • 外部不一定意味着不是 PHP。 Smarty 是一个纯 PHP 模板引擎,构建为一组类。并且你可以构建自己的模板引擎,基本的一点是使用模板引擎将视图与逻辑分开,从而可以很容易地显示不同版本的视图。
    • 如果您在构建视图文件时足够严格,那么您的视图文件可能符合模板引擎的条件,但使用单独的引擎可以更快并提高效率。
    【解决方案4】:

    使用模板,您还可以将演示文稿的职责委托给设计师。设计人员可以创建模板,开发人员可以在逻辑中工作。保持演示文稿的一致性也更容易。

    【讨论】:

    • 根据我的经验,这是唯一正当的理由。单独工作时,更容易将“模型逻辑”分隔在自己的文件中,并将“视图逻辑”放在每个页面的 PHP 顶部,底部用于“模板 PHP”代码,只有单行变量和循环插入.
    【解决方案5】:
    1. 我使用自己的“模板”引擎,非常基本的东西,将value 分配给[key] 等等。
    2. 当我第一次寻找模板引擎时,我发现它很聪明,但它存在很多安全问题,我最终自己编写了我需要的东西。
    3. 你问为什么?因为它有许多功能可以让你的编码更快(你没有想到的东西和你可以委托给模板系统而不是你的代码的东西)
    4. 大多数编码人员都选择了模板系统,在团队中工作时,您需要保持标准。

    【讨论】:

      【解决方案6】:

      如果您想开发可以使用许多不同模板和布局进行自定义的应用程序,同时保持设计与逻辑分离,例如对于不同的客户,您可能需要考虑使用模板系统。

      但是,如果您的应用程序只需要 一个 模板并且从不大量更改布局,那么坚持适合您的,为什么要更改? :)

      【讨论】:

        【解决方案7】:

        一些模板引擎可以编译模板,从而实现高度优化的转换。 以 .NET 中的XslCompiledTransform 为例。

        【讨论】:

          【解决方案8】:

          您的未回答看起来像真正的回答,但措辞非常居高临下。例如:

          照看糟糕的开发人员(即使用模板引擎,因为它迫使您不要将代码混入演示文稿中)

          我将其称为Rule of Least Power 的应用程序。它使您的模板对所有用户都更加有用,而不仅仅是“糟糕的开发人员”。

          限制是编程语言的组成部分。 PHP 没有内联汇编功能,也不是因为 Rasmus 认为你们都是“婴儿”。

          【讨论】:

            【解决方案9】:

            当我需要沙盒时,我发现自己使用模板引擎。例如,让托管 CMS 的用户编辑模板。

            【讨论】:

              【解决方案10】:

              首先解决这里的答案和一般背景:

              人们使用它们的主要原因是它们通常会使事情变得更简洁。这是否总是一个净收益值得怀疑。学习一门新语言而增加的认知负担和手头没有宿主语言的灵活性最终会带来比使用模板语言更多的缺点。 Twig 特别需要手动向其导出核心 PHP 函数。寻求简洁的最佳模板语言会更好,而不是使用标记器扩展 PHP。

              自动转义是另一个值得怀疑的功能。对于代码非常糟糕的开发人员来说,自动转义可能更安全,但否则会削弱安全性,让人忘记它并提出在任何情况下默认情况下一切都是安全的期望。一个真正安全的模板引擎需要了解很多关于其上下文的信息,有时这并不总是可以确定的,只有程序员知道某些事情的去向。如果您需要安全编程,您需要有一个不依赖于自动转义的开发人员。这也是 PHP 实际上可以做的事情,如果您对 PHP 文件进行标记,您可以将原始文本与 PHP 分离并将 PHP 部分包装在输出缓冲中,然后应用您喜欢的任何过滤器,因此这不是模板语言独有的功能。

              一些模板引擎可以使预生成更容易一些,预编译使它们更快,但这也可以通过原生模板来实现。有必要解析模板,这通常会降低它们的效率并且使用它们的过程更加复杂。引入的增加的复杂性模板意义重大。这通常可以从您身上抽象出来,但最终会困扰您,例如缓存问题(陈旧的条目),性能问题,调试时明显更多的混乱和混乱,更多的层和更多的代码被执行,更多可能出错等。

              许多功能(例如扩展模板)无需使用 twig 即可实现。类似地,对于诸如 htmlspecialchars 之类的东西,大多数人会为他们经常使用的所有函数创建简短的辅助函数。

              那么您应该肯定在哪里使用 Twig 等模板语言?

              1. 婴儿坐在糟糕的开发人员有点有效,尽管我不确定如果您必须使用诸如 twig 之类的东西来尝试包含它们,他们是否应该被视为开发人员。您还会惹恼优秀的开发人员,您会想知道为什么要让他们越过障碍来完成原本简单的事情。

              2. 您可能希望将模板提供给您可能希望处理 HTML 但不公开系统内部等的各方。例如,这可能是您拥有 CMS 的地方,用户可以编辑模板但与您的开发人员不同。这与上述情况有关,但这是一个更真实的案例,您可能会从中受益并且可能是合理的。

              3. 类似的情况是您可能希望在系统之间使用模板,在这种情况下,模板语言可以是一种可移植的解决方案。这可能不仅是您拥有多个后端的地方,而且您还有不寻常的架构要求,例如前向服务器从下游派生的数据呈现视图。更进一步,您可能需要可以呈现前端或后端的模板。如果您只需要将数据发送到前端,因为它可以自己呈现视图,那么这可能会更有效。但是,由于各种原因,您可能还必须回退到后端。

              4. 另一种情况是静态分析,包括跨多种语言。大多数语言通过字符串连接有效地进行模板化,并且不知道您正在生成的语言。在某些情况下,当您可以完全解析语言和 HTML 时,模板语言可以提供好处。实现这一点的另一种方法是尽可能多地使用 HTML 本身进行模板来表示事物,例如使用类等,以及 HTML 提供的允许您将行为附加到事物的工具。模板语言也可以比 PHP 更易解析,即使您无法解析您正在使用的模板语言。这可用于优化或拥有更容易转译的模板。

              5. 您的语言确实不适合创建 HTML 和其他语言。 PHP 是一种模板语言,因此在大多数情况下,使用模板语言几乎没有什么作用,但会产生很大的拖累。但是,如果您使用的是 Java 之类的东西,那么您很可能需要一个模板引擎。模板语言是一种 DSL,但如果你已经有一个 DSL 可以很好地完成它们的工作,那么它就是 YAGNI。

              6. 定制模板。如果您有特定的输出格式和域,可以从定制的模板语言中显着受益。这取决于您的输出格式。

              所有这些情况都是针对特定情况的,并且不够普遍,因此默认情况下应使用模板语言。模板语言仅以不同程度的成功解决了这些问题(例如,许多不支持 HTML)。如果我将 Twig 排在 10 分(满分 10 分)中的每一项表现如何,那么平均分也不会差到 5 分。

              您可以将 Twig 转换为 PHP,但不能将 PHP 转换为 Twig。这有时会很有用,但代价是相当大,因为您失去了 PHP 的很多灵活性。

              在我接触过的少量 Twig 内部构件中,质量也很差,或者进口的标准不合格。例如,五年前我第一次尝试时,解析器不支持或至少不支持保留空格。我有一个需要重构的场景,这意味着我需要能够解析 Twig,修改并再次输出它以在数千个模板中重写代码,twig 不支持它,我不得不自己翻阅解析器。

              同样,我最近调查了 Twig 的逃逸行为。特别是 JS 转义,它支持转义 JS 字符串和其他奇怪的东西,而不是简单地使用 json_encode。您在框架中得到的自定义转义很可能是错误的。自己做通常更可靠和安全(只要你知道如果你 JSON 编码一个包含它的字符串并将其模板化为没有足够转义的 javascript 文字会发生什么,例如)。

              在大多数情况下,成百上千行的魔术模板系统和其他相关系统实施的转义、消毒等都是糟糕的做法,试图猜测您的场景或尝试迎合每一个可能的场景,从而为数据损坏的奇怪错误,增加更多安全错误的机会等。通常你会发现框架中的类似东西可以用更安全的一两行函数替换。您有时还会遇到其他愚蠢的事情,例如一遍又一遍地处理某些事情以防万一,因为框架对于您正在做什么很天真,好像您自己做的事情您确切地知道自己在做什么和不做什么'然后会有一些事情,比如一遍又一遍地清理同一个字符串。

              【讨论】:

                猜你喜欢
                • 2019-12-13
                • 1970-01-01
                • 2016-07-03
                • 2010-09-24
                • 2010-12-27
                • 2015-04-06
                • 2013-05-09
                • 2017-05-29
                • 2017-11-24
                相关资源
                最近更新 更多