PHP - 使用自定义标签的模板 - 这是 eval 的合法使用吗?

2023-11-27

Overview

大约在 2009 年底,我为 PHP/HTML 编写了一个简单的模板系统,供我们的设计人员在内部使用小册子软件类型的网站。该系统的目标是允许通过由 PHP 处理的自定义标签在其他纯 HTML 中进行模板化。例如,模板化页面可能如下所示:

<tt:Page template="templates/main.html">
  <tt:Content name="leftColumn">
    <p> blah blah </p>
    ...
  </tt:Content>
  <tt:Content name="rightColumn">
    <p> blah blah </p>
    ...
  </tt:Content>
</tt:Page>

模板本身可能看起来像这样:

<html>
  <head>...</head>
  <body>
    <div style="float:left; width:45%">
      <tt:Container name="leftColumn" />
    </div>
    <div style="width:45%">
      <tt:Container name="rightColumn" />
    </div>
  </body>
</html>

除了页面和内容/容器标签之外,核心中还包含一些其他标签,用于流量控制、迭代集合、输出动态值等。该框架的设计使得您可以很容易地添加自己的一组标签在另一个前缀和命名空间下注册的标签。

PHP 的自定义标签

我们如何解析这些自定义标签?由于无法保证 HTML 文件是格式良好的 XML,因此 XSLT/XPATH 等解决方案并不可靠。相反,我们使用正则表达式来查找具有已注册前缀的标签,并将其替换为 PHP 代码。 PHP 代码是基于堆栈的设计......在遇到开始标记时,会创建一个表示该标记的对象并将其推送到堆栈上,并且其“初始化函数”(如果有)运行。每当遇到注册的结束标记时,最新的对象就会从堆栈中弹出,并且其“渲染函数”运行。

因此,在框架用 PHP 替换模板标签后,我们的示例页面可能看起来像这样(实际上它有点难看):

<?php $tags->push('tt', 'Page', array('template'=>'templates/main.html')); ?>
  <?php $tags->push('tt', 'Content', array('name'=>'leftColumn')); ?>
    <p> blah blah </p>
    ...
  <?php $tags->pop(); ?>
  <?php $tags->push('tt', 'Content', array('name'=>'rightColumn')); ?>
    <p> blah blah </p>
    ...
  <?php $tags->pop(); ?>
<?php $tags->pop(); ?>

好的、坏的以及eval

现在,如何执行我们新生成的 PHP 代码?我在这里可以想到几个选择。最简单的就是简单地eval字符串,效果很好。然而,任何程序员都会告诉你“eval 是邪恶的,不要使用它......”所以问题是,还有什么比eval我们可以在这里使用吗?

我考虑过使用临时文件或缓存文件,使用php://输出流等,但据我所知,这些并没有提供任何真正的优势eval。缓存可以加快速度,但实际上我们在这方面拥有的所有网站都已经非常快了,所以我认为此时没有必要进行速度优化。

问题

对于此列表中的每件事:这是一个好主意吗?你能想出更好的选择吗?

  • 总体思路(html / php 的自定义标签)
  • 将标签转换为php代码而不是直接处理
  • 基于堆栈的方法
  • 指某东西的用途eval(或类似)

感谢您的阅读以及 TIA 的建议。 :)


让我提倡一种不同的方法。不要动态生成 PHP 代码,然后尝试找出如何安全地执行它,而是在遇到标签时直接执行它。你可以一次性处理整个 HTML 块,并在遇到每个标签时对其进行处理立即地。

编写一个查找标签的循环。它的基本结构如下所示:

  1. 查找自定义标签,您可以在位置找到该标签n.
  2. 位置之前的所有内容n必须是简单的 HTML,因此要么将其保存以进行处理,要么立即输出(如果您的$tags堆栈,您可能不需要将其保存在任何地方)。
  3. 为标签执行适当的代码。而不是生成调用的代码$tags->push,只需调用$tags->push直接地。
  4. 返回步骤 1。

使用这种方法,您只需直接调用 PHP 函数,而无需即时构建 PHP 代码,然后再执行。需要eval离开了。

步骤#3 基本上有两种情况。当您遇到开始标签时,您将立即执行push。然后当你点击结束标签时你可以做pop现在您已经处理了自定义元素的全部内容,然后以适当的方式处理标记。

以这种方式处理 HTML 也更加高效。对长 HTML 字符串进行多次搜索和替换效率很低,因为每次搜索和每次替换在字符串长度上都是 O(n)。这意味着您一遍又一遍地重复扫描字符串,每次进行替换时,您都必须生成长度相似的全新字符串。如果您有 20KB 的 HTML,则每次替换都需要搜索该 20KB,然后创建一个新的 20KB 字符串。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PHP - 使用自定义标签的模板 - 这是 eval 的合法使用吗? 的相关文章

  • 如何启用 php curl 以在 php cli 中使用

    我已经在没有服务器的情况下在我的计算机上安装了 php 并使用 cli 运行它 但未启用 php curl 我不知道如何执行此操作 如果有人遇到此线程并使用 wamp 服务器 这里有一个针对上述问题的快速解决方案http forum wam
  • PHP 数据库显示在具有不同锚标记的相同字段中

    我四处寻找 看看这是否可行 但却空手而归 首先 这是我的代码 div style display none div ul li li li li li li ul
  • 框架可以用什么代替?

    假设我有一个包含 50 个网页的网站 每个页面由 A Header 导航 左侧内容 右侧内容 Footer 不使用 Frames 服务器端编程 第三方工具和软件 构架 我需要将这 5 个部分的代码 HTML 标记 分别放入这 50 个页面中
  • JavaScript 原型继承和 html canvas

    我是一名 Ruby 开发人员 最终决定认真学习 JavaScript 所以我买了一些书 开始深入研究 但当我试图理解原型继承时 我很快就陷入了困境 这本书的例子之一如下 给定一个 Shape 其原型有一个绘制方法 以及两个子形状 一个 Tr
  • 动态添加jinja模板

    我有一个 jinja 模板 它是一组 div 标签内的唯一内容 div include temppage html div 当我按下按钮时 我想用其他内容替换标签之间的所有内容 我希望用另一个 jinja 模板 include realpa
  • 在嵌入式 Jetty 上使用 DefaultServlet 提供静态 html 文件

    我正在开发一个需要独立的项目 因此我决定将 Jetty 嵌入到我的应用程序中 我将提供静态 HTML 页面 一些 JSP 页面 并且还将使用一些自定义 servlet 我找到了一个完美的示例 说明如何设置嵌入式 Jetty 来完成所有这一切
  • 如何在没有数据库的情况下创建AJAX分页?

    是否可以在没有 MySQL 帮助的情况下获取 AJAX 分页页面 难道我不能只添加一个包含我需要显示的文本和标记的 PHP 文件 然后通过单击页码将该内容提供给用户吗 那么可以用纯 jQuery 和 PHP 来实现吗 您会使用什么代码方法来
  • CSS3输入元素的圆角,没有js/图像

    谁可以为输入元素制作圆角 我需要一种不使用 javascript 和图像的方法 Added
  • 根据客户端发送 HTML 或 JSON 响应

    我有一个带有 Eloquent 实体及其各自的 Laravel 应用程序RESTful 资源控制器 http laravel com docs 5 0 controllers restful resource controllers 如下所
  • mysqli_stmt_bind_result 的奇怪问题

    好吧 这让我很烦恼 我似乎在 PHP 文档中找不到任何内容 在 Google resultosphere 中也找不到任何内容 所以也许有人可以在这里提供帮助 我正在使用准备好的语句 绑定结果 然后使用这些绑定结果来填充下拉列表 例子
  • php循环中的ajax在按钮单击时执行操作

    所以我有一个 php 循环 我使用 jquery 滑动切换来隐藏 显示带有 sql 结果的表 目前该表仅使用 php 加载 但由于发生了很多事情 导致了一些加载问题 我需要使用滑动切换 btn 来触发 ajax 因此它仅在按下按钮时请求当前
  • 如何找到 httpd.conf 文件所在的位置?

    如何找到 apache PHP 上 httpd conf 文件的路径 我不知道我的脚本是否会在Windows apache或Linux中运行 我需要知道在哪里可以找到这个文件 以便从那里找到参数 谢谢 我认为它没有接触 PHP 跑步http
  • Firefox CSS 旋转与 Chrome 旋转不同

    我想制作一个 3D 矩形 平行六面体 用户可以用箭头移动它 它在 Chrome 中工作得很好 但在 Firefox 中 一些转换 实际上很多 与 Chrome 不同 看着this https jsfiddle net 7273yur9 2
  • 有没有办法获取 PHP 中可用区域设置的列表?

    在Java中 你可以调用Locale getAvailableLocales 获取可用区域设置的列表 我期待 PHP 的同等功能Locale http php net manual en class locale php类 但找不到 有没有
  • 在 PHP 中创建关联数组

    我有一个多维数组 shop array array appn1 pub1 pub2 pub3 array appn2 pub1 array appn3 pub1 pub2 每个数组中的第一项是申请编号每个数组中的其余部分是出版号 我得到每个
  • Struts html:text 标签内的 HTML5 占位符

    我在 Web 应用程序中使用 Struts 1 3 10 并且希望我的文本字段有一个占位符 不幸的是 当前的 Struts taglib 无法识别此属性 如果可能的话 我希望避免使用 javascript 你知道有什么解决办法吗 Strut
  • ZF2 - 从路线生成 URL

    我无法弄清楚在 zend 2 中从我想要的任何地方生成 Url 我得到了动作和控制器 所以我尝试这个 this gt url myControllerName array action gt myActionName 但这返回一个对象 我只
  • 可以在 IE 中的表格行上添加渐变吗?

    当我将鼠标悬停在表格特定部分的表格行上时 我希望背景更改为线性渐变 CSS 很简单 tbody row links tr hover background typical multi browser linear gradient code
  • 检测 HTML5 视频何时结束

    如何检测 HTML5
  • Django:单击按钮加载另一个模板

    我已经在 django 项目上工作了几个星期 只是玩玩以便掌握它的窍门 我有点困惑 我现在有一个名为 home html 的模板 我想知道是否可以将另一个名为 profile html 的模板设置为 home html 模板上的链接 我有一

随机推荐