【发布时间】:2012-10-12 09:07:08
【问题描述】:
概述
我目前正在编写模板引擎。它甚至支持多种“格式”。目前它可以解析.php文件和.tpl(特定于这个引擎)。
我会给你一个两者的小例子,只是为了给你一个想法。
template.php:
Name: <?php echo $this->h($name) ?>
Posts:
<?php foreach($posts as $post): ?>
- <?php echo $this->h($post->name) ?> (<?php echo count($post->comments) ?> comments)
<?php echo $this->render('post/shortpost', array('post' => $post)) ?>
<?php endforeach ?>
这基本上只是一个标准的 PHP。
template.tpl
Name: {>$name}
Posts:
{foreach($posts as $post):}
- {>$post->name} ({=count($post->comments)} comments)
{=:render('post/shortpost', array('post' => $post))}
{endforeach}
这个模板“语言”简单地被翻译成上面的 PHP。
比较
eval()
目前这些模板是使用 eval() 解析的。
专业版
- 我不需要更改任何代码
对比
- 当模板中发生错误时,您只会收到一条无用的错误消息,它不会 告诉你错误发生在哪个文件中,有时行号甚至是错误的。
- 安全?模板文件只需要可读?
- 很难调试代码。
- 代码更难理解
- 更多.. ?
流包装器和 include()
我最近读到了 php 中的流包装器。你甚至可以创建自己的。除了eval 之外的另一种解决方案是为每个模板“格式”创建一个自定义流包装器,并使用 include 来解析模板。
这有以下(潜在的)缺陷:
专业版
- 可能会解决在错误消息中显示错误文件/行号的问题(有人遇到过这种情况吗?)
- 您可以按照希望的方式处理模板文件。完全控制。
对比
-
allow_url_(fopen|include)必须打开? - 很慢? (
eval()也很慢吗?) - 没有获得安全性。 include 的作用与 eval 基本相同。
- 更多...?
编辑:缓存的解析文件和include()
第三种选择是将模板解析为 PHP 代码并缓存它们(如 @Jen-YaKovalev 所建议的那样)。
专业版
- 包括缓存
对比
- 如果在包含呈现的模板时发生错误并且发生错误 错误消息不会将您指向正确的文件/最终会显示给您 错误的行号。
- 您需要一个额外的
tmp/目录来保存已解析的文件。你需要写 PHP/网络服务器的权限。会更不安全,因为黑客 会更容易附加一些恶意代码。
编辑: 流过滤器和包含('php://filter')
最近发现了以下php.net页面:
-
php://filter:http://php.net/manual/en/wrappers.php.php -
strea_filter_registerhttp://fr2.php.net/manual/en/function.stream-filter-register.php
这将是解决此问题的另一种可能性。使用include('php://filter/read=filtername/resource=file.php'),我可以包含一个文件,该文件将在执行之前首先通过过滤器filtername。
专业版
- 不需要像流包装器那么多的代码
对比
- 没有像使用流包装器(缓存?)那样的可能性
- 安全吗?
- 速度?
问题
- 有使用流包装器解析模板文件或类似文件的经验吗?
- 还有其他解决方案吗?
- 还有更多的专业人士和反对者吗?
- 您会推荐哪一款?
【问题讨论】:
-
我认为,这里最好的方法是缓存模板。您基本上生成 php 文件并执行它们。它还可以提高应用程序的性能和可扩展性。
-
eval 有 100 个缺点,我的意思是假设用户能够在评估之前将 PHP 字符串回显到您的模板中,因为使用了不同的缓冲区。通常人们会在这里使用正则表达式和其他解析函数来动态运行某些子句,它很慢,但它比流包装器稍微好一点。
-
@Jen-YaKovalev 我还可以使用 eval() 缓存已解析的模板并包含
-
@Sammaye include 与 eval() 几乎完全相同。
include "data:image/png;base64," . base64("<?php // do badass stuff ?>") -
@BryanAllo 只是因为我可以。我做这个教育和乐趣。这也是我目前正在编码的框架的一部分。我不使用任何其他模板引擎,因为我可以自己做,我想自己做,而且我也有很多时间。我的依赖也少了。
标签: php eval template-engine stream-wrapper