0

我有一个表单,用户可以在其中将全局通知发布到系统中(供其他用户查看)。
系统直接从 DB 输出 HTML(当用户想要查看通知时)。
我想让一些 html 标签保持完整,并让其余的标签应用 htmlspecialchars()。
我已经尝试申请

 str_replace($search, $replace, htmlspecialchars($str))

策略,但它似乎真的很慢。其实太慢了 而且总是有效的也不安全,有没有替代方案?
我想要做 strip_tags() 工作的东西,除了它,而不是条带化标签,它将 htmlspecialchars 应用于不允许的标签。

ADD(ed) info (by request):

$str 可以是你能想到的任何大小。我考虑使用一个大字符串(1M 个字符(随机生成,其中包含一些允许和一些不允许的标签。所有标签都有属性),因为它是测试最坏情况之一的原因 逻辑:如果它像这样工作,它应该适用于更简单
的情况。服务器需要 5 秒来处理完整的 str_replace(使用 htmlspecialchars)。这个测试是在我的具有 2GHz CPU 和 DDR3 RAM 的计算机上进行的。
$search 和 $replace 总共有 7 个替换。他们仍然这样做并非总是有效。在某些情况下,$search 会给出误报或漏报。
为了澄清,我在保存到数据库时应用这些更改,而不是在从数据库检索时应用这些更改。

4

2 回答 2

1

str_replace随着htmlspecialcharsISN不慢。

可能你在其他地方有一些瓶颈。

于 2011-06-03T10:07:46.960 回答
1

你可以试试这段代码(应该改进):

function callback(array $matches) {
    return htmlspecialchars_decode($matches[0]);
}
$str = 'some <i>string</i> <b>with</b> tags '
     . '<a href="#">some link</a> '
     . '<img alt="" src="http://sstatic.net/stackoverflow/img/favicon.ico"/><hr/>';
$str = htmlspecialchars($str);
$str = preg_replace_callback('#(&lt;(i|a)(?: .+?)?&gt;.*?&lt;/(\1)&gt;|&lt;(?:img)(?: .*?)?/&gt;)#', 'callback', $str);
echo $str;

正则表达式查找(应该查找)两种类型的字符串:

  • <tag attributes>content</tag>,tag部分与打开结束标签相同,attributes并且content是可选的
  • <tag attributes/>,attributes是可选的

(i|a)部分列出了<tag></tag>标签类型和标签类型(?:img)<tag/>标签。

如果找到匹配的标签,它会将内容传递给callback()函数,该函数使用htmlspecialchars_decode(). 这对于解码属性列表中的引号和其他编码字符是必要的。

我不确定它是否适用于所有情况,即它是否匹配所有必要的标签。如果这通常有效,callback()则应改进模式和功能,以便callback()仅解码<>字符和属性列表;不得解码标签的内容(即,some link部分)。<a href='#'>some link</a>

于 2011-06-03T10:46:58.550 回答