在post中将实体转换为不允许的标记并允许标记

时间:2011-06-03 10:06:05

标签: php post htmlspecialchars

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

 str_replace($search, $replace, htmlspecialchars($str))
战略,但似乎真的很慢。实际上太慢了。并且它总是有效并不安全,是否有替代方案?
我想要一些做strip_tags()工作的东西,除了它,而不是条带化标签,它会将htmlspecialchars应用于不允许的标签。

ADD(ed)info(按要求):

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

2 个答案:

答案 0 :(得分:1)

str_replace以及htmlspecialchars并不慢。

很可能你在其他地方遇到了一些瓶颈。

答案 1 :(得分: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部分与开放相同 结束标记,attributescontent是可选的
  • <tag attributes/>attributes是可选的

标记列在(i|a)部分中<tag></tag>种类型的代码中,(?:img)代表<tag/>种类型的代码。

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

我不确定它是否适用于所有情况,即它是否匹配所有必要的标签。如果这一般起作用,那么应该改进模式和callback()函数,以便callback()仅解码<>个字符和属性列表;标签的内容(即some link中的<a href='#'>some link</a>部分)不得解码。