【问题标题】:How do I insert html code into a php regex?如何将 html 代码插入 php 正则表达式?
【发布时间】:2020-07-26 09:42:22
【问题描述】:

所以我目前正在制作一个论坛软件。我想要的那个论坛软件是一个自定义模板引擎。在大多数情况下,我已经创建了模板引擎,但我在 IF、ELSEIF 和 FOREACH 语句中使用的正则表达式存在一个小问题。

我遇到的问题是,当我将一大段 html 代码放入我的正则表达式时,什么都不起作用。这是一个示例:https://regex101.com/r/jlawz3/1

这是检查正则表达式的 PHP 代码。

        $isMatchedAgain = preg_match_all('/{IF:(.*?)}[\s]*?(.*?)[\s]*?{ELSE}[\s]*?(.*?)[\s]*?{ENDIF}/', $this->template, $elseifmatches);
        for ($i = 0; $i < count($elseifmatches[0]); $i++) {
            $condition = $elseifmatches[1][$i];
            $trueval   = $elseifmatches[2][$i];
            $falseval  = (isset($elseifmatches[3][$i])) ? $elseifmatches[3][$i] : false;
            $res = eval('return ('.$condition.');');
            if ($res===true) {
                $this->template = str_replace($elseifmatches[0][$i],$trueval,$this->template);
            } else {
                $this->template = str_replace($elseifmatches[0][$i],$falseval,$this->template);
            }
        }

【问题讨论】:

  • ...我已经创建了模板引擎... 为什么要重新发明轮子?只需带一些像 smarty 或 slim 这样的 TE,然后做你的事情,而不用担心代码。请记住,您要制作“论坛软件”-而不是模板引擎;)
  • 真的有两个原因,首先,在论坛软件中,如果我允许用​​户在模板内使用php,那么它会带来很大的安全风险。另一个原因是因为我想创建一个模板引擎。我编程的主要原因是学习不同的做事方式,所以我正在制作一个模板引擎来学习如何去做。
  • 这个问题的唯一正确答案(已经被问了很多......)是“不要”。如果您不信任我们,请参阅这个投票率很高的问题stackoverflow.com/questions/1732348/… 不要这样做。使用正确的工具来完成工作....或在此处发布论坛链接,以便我们都知道要避免它,以免我们的个人信息成为您傲慢的牺牲品。

标签: php html regex


【解决方案1】:

你可以这样做:

function render($content) {
    $match = preg_match_all('/{IF:\((.*?)\)}(.*?){ELSE}(.*?)({ENDIF})/s', $content, $matches, PREG_OFFSET_CAPTURE);

    if (!$match) {
        return $content;
    }
    
    $beforeIf = substr($content, 0, $matches[0][0][1]);
    $afterIf = substr($content, $matches[4][0][1] + strlen('{ENDIF}'));
    $evalCondition = eval('return (' . $matches[1][0][0] . ');');
    
    if ($evalCondition) {
        $ifResult = $matches[2][0][0];
    } else {
        $ifResult = $matches[3][0][0];
    }
    
    return
        $beforeIf .
        $ifResult .
        render($afterIf);
}

工作example

这是第一步。例如,如果您在 if 中有一个 if,这将不起作用。

谈到提到的安全风险。由于我们使用的是 eval(昵称 EVIL - 出于某种原因)。您永远不应该通过 eval 处理用户输入 - 或者根本不使用 eval - 总会有更好的解决方案。

对我来说,您似乎希望让用户能够在他们的帖子中编写“代码”。如果是这种情况,您可以查看 bbcode 之类的内容。

无论您做什么,一定要提供所需的功能。以你为例:

!isset($_SESSION['loggedin'])

你可以这样做:

{IS_LOGGED_IN}
    Output whatever you want :)
{/IS_LOGGED_IN}

你的渲染器会专门寻找这个标签并采取相应的行动。

【讨论】:

  • 虽然我非常重视您的意见,但您所做的只是围绕我的示例工作。使用您提供的 php 代码块,我将无法做我能做的事情。您删除循环以查找所有匹配项并替换它们,这不适用于我的系统。我还需要能够在任何条件下使用任意数量的 html 代码,这是我的问题。我不能放一大块 html 代码,因为 会破坏它。而且它是一个模板引擎,不是帖子,所以 bbcode 不会做我想做的,这不是标记。
  • 所以你想在一个 $content 中有多个 if 对吗?我已经更新了答案。
  • $content 是一个包含 html 内容的文件,但其中也有我的模板引擎标签。所以是的,我需要能够在单个$content 中包含多个 if。我还需要能够在 if 语句中包含尽可能多的 html 代码行。
  • 你现在可以添加尽可能多的 ifs 和 html :) - 只是不要在 if 中使用 ifs - 我为你保留它。
  • 我打赌,编码愉快 :) 尽力而为,如果遇到困难,请随时创建一个新问题。
【解决方案2】:

所以经过一番研究,我发现我所面临的问题可以通过在我的正则表达式语句的末尾添加 /ims 来解决。所以现在我的正则表达式语句看起来像:

/{IF:(.*?)}[\s]*?(.*?)[\s]*?{ELSE}[\s]*?(.*?)[\s]*?{ENDIF}/ims

【讨论】:

  • 感谢分享,遗憾的是这并不能解决if within if 问题:/ - 提示,您无法使用单个正则表达式解决嵌套元素。此外:您只需要 s 选项 :)
  • 感谢您通知我。但我会对正则表达式语句进行一些修改以适应 if 语句中的 if
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-18
  • 1970-01-01
相关资源
最近更新 更多