【问题标题】:PHP convert string to htmlentitiesPHP将字符串转换为htmlentities
【发布时间】:2011-07-28 10:35:39
【问题描述】:

如何将<code><pre> 标签内的代码转换为html 实体?

<code class="php"> <div> a div.. </div> </code>

<pre class="php">
<div> a div.. </div>
</pre>

<div> this should be ignored </div>

【问题讨论】:

  • 取决于上下文。代码在哪里?在字符串中?
  • 是的,它是 php 字符串变量
  • @Alexandra 这很难,因为您需要首先解析结构,以区分您需要实体化的部分和不需要实体化的部分。为什么一开始就这么混?你能影响它的生成方式吗?
  • 我不能......这是访问者发表评论时的输出,我希望他们也能够发布 html
  • @Alexandra 您不能只让访问者将 HTML 发布到您的网站 — 这会导致 XSS 攻击并允许机器人发布非常讨厌的垃圾邮件,这些垃圾邮件对普通访问者是不可见的,但对搜索引擎机器人来说是可见的。

标签: php string html-entities


【解决方案1】:

好的,我已经玩了一段时间了。结果可能不是最好或最直接的解决方案(坦率地说,如果任意用户要提交输入,我完全不同意您的方法),但它似乎“有效”。而且,最重要的是,它不使用正则表达式来解析 XML。 :)

伪造输入

<?php

$str = <<<EOF
<code class="php"> <div> a div.. </div> </code>

<pre class="php">
<div> a div.. </div>
</pre>

<div> this should be ignored </div>
EOF;

?>

代码

<?php

function recurse(&$doc, &$parent) {
   if (!$parent->hasChildNodes())
      return;

   foreach ($parent->childNodes as $elm) {

      if ($elm->nodeName == "code" || $elm->nodeName == "pre") {
         $content = '';
         while ($elm->hasChildNodes()) { // `for` breaks the `removeChild`
             $child = $elm->childNodes->item(0);
             $content .= $doc->saveXML($child);
             $elm->removeChild($child);
         }
         $elm->appendChild($doc->createTextNode($content));
      }
      else {
         recurse($doc, $elm);
      }
   }
}

// Load in the DOM (remembering that XML requires one root node)
$doc = new DOMDocument();
$doc->loadXML("<document>" . $str . "</document>");

// Iterate the DOM, finding <code /> and <pre /> tags:
recurse($doc, $doc->documentElement);

// Output the result
foreach ($doc->childNodes->item(0)->childNodes as $node) {
   echo $doc->saveXML($node);
}

?>

输出

<code class="php"> &lt;div&gt; a div.. &lt;/div&gt; </code>

<pre class="php">
&lt;div&gt; a div.. &lt;/div&gt;
</pre>

<div> this should be ignored </div>

证明

你可以看到它在工作here

注意它没有显式调用htmlspecialcharsDOMDocument 对象自己处理转义。

我希望这会有所帮助。 :)

【讨论】:

  • 我的代码似乎也可以工作......你的代码和我的一样容易坏。 PS 我比你少浪费了 16 分钟。
  • @webarto:感谢您的非建设性评论。您能否提供一个破坏我的代码的输入示例,以便我修复它? PS 如果您在 Stack Overflow 上帮助人们,这不是一种浪费。现在是 12 分钟。
  • 我刚刚注意到 HTML 似乎被转义了两次。现在已修复。
  • 它不是非建设性的(codepad.org/FulWwCbC),如果你只添加一个没有打开的结束标签,它会带来致命的错误,反正你的代码很花哨,但在实际情况下它毫无价值,只是和我一样。
  • @webarto:当然,需要有效的 XML。这是我想我应该在答案中提到的先决条件。
【解决方案2】:

您可以使用 jquery。这将使用 code 类对任何标签内的任何内容进行编码。

$(".code").each(
    function () {
        $(this).text($(this).html()).html();
    }
);

小提琴:http://jsfiddle.net/mazzzzz/qnbLL/

【讨论】:

  • +1 只要结果 HTML 不是不安全的,我会推荐这种方法。
  • 这个问题是关于 PHP,而不是 Javascript。
  • 但是如果代码被转义,你怎么能被黑客入侵呢? stackoverflow 做同样的事情......
  • @Alexandra:不,它没有。 Stack Overflow 接受严格的 HTML 子集。您拒绝 HTML 的严格子集。
  • @Tomalak 但我只对 CODE 中的内容执行此操作。在评论的其余部分,我正在剥离标签,就像 SO
【解决方案3】:

PHP

if(preg_match_all('#\<(code|pre) class\=\"php\"\>(.*?)\</(code|pre)\>#is', $html, $code)){
    unset($code[0]);
    foreach($code as $array){
        foreach($array as $value){
            $html = str_replace($value, htmlentities($value, ENT_QUOTES), $html);
        }
    }
}

HTML

<code class="php"> &lt;div&gt; a div.. &lt;/div&gt; </code>

<pre class="php">
&lt;div&gt; a div.. &lt;/div&gt;
</pre>

<div> this should be ignored </div>

您听说过 BB 代码吗? http://en.wikipedia.org/wiki/BBCode

【讨论】:

  • 这不是很灵活。您要求标签具有非常严格的文本布局。
  • 我不明白,它和你的一样容易坏,不严格的布局只是一种黑客攻击。
  • @webarto:不,它更容易坏掉。我的需要有效的 XML;你的需要完全匹配的文本。用户不能在标签内写更多的空格(否则有效),或在标签中添加更多参数(这也是有效的)。你的也匹配&lt;code&gt;...&lt;/pre&gt;
  • 完全匹配是指&lt;code class="php"&gt;&lt;/code&gt;?是的。但应该严格。我可以在codepre 标记中插入内联CSS 或JS 吗? (无论如何这都没有意义,因为在这种情况下您可以在外部使用 HTML)。是的,它匹配&lt;code&gt;...&lt;/pre&gt;。但有效的 XML 是先决条件:)
  • @webarto: &lt;code class="php"&gt;&lt;pre class="php"&gt;A&lt;/pre&gt;B&lt;/code&gt; 是有效的 XML,但您的代码(我相信)无法在其中转义 B
【解决方案4】:

这有点相关,您不必使用 Geshi,但我在这里写了一些代码Advice for implementing simple regex (for bbcode/geshi parsing) 可以帮助您解决问题。

它可以被调整为不使用 GeSHi,只是需要一些修补。希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 2014-11-02
    • 2017-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多