我有一个表单,用户可以将全局通知发布到系统中(供其他用户查看)
系统直接从DB输出HTML(当用户想要查看通知时)
我想允许一些html标签保持不变,并使用htmlspecialchars()应用其余部分。
我已经尝试过申请
str_replace($search, $replace, htmlspecialchars($str))
战略,但似乎真的很慢。实际上太慢了。并且它总是有效并不安全,是否有替代方案? ADD(ed)info(按要求):
$ str可以是你能想到的任何大小。我想过使用一个大字符串(1M字符(随机生成一些允许的内容和一些不允许的标签。所有标签都有属性),因为测试最坏情况之一的原因是逻辑:如果它像这样工作,它应该为更简单的案件工作
服务器花了5秒来处理完整的str_replace(使用htmlspecialchars)。这个测试是在我的计算机上进行的,它有2GHz CPU和DDR3 RAM
$ search和$ replace共有7个替换。他们仍然不总是工作。在某些情况下,$ search会出现误报或漏报
为了澄清,我在保存到数据库时应用这些更改,而不是从数据库中检索时。
答案 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('#(<(i|a)(?: .+?)?>.*?</(\1)>|<(?:img)(?: .*?)?/>)#', '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>
部分)不得解码。