如何以比使用 strip_tags 函数更安全的方式剥离标签?
Posted
技术标签:
【中文标题】如何以比使用 strip_tags 函数更安全的方式剥离标签?【英文标题】:How to strip tags in a safer way than using strip_tags function? 【发布时间】:2011-06-27 03:03:34 【问题描述】:当字符串包含“小于”和“大于”符号时,我在使用 strip_tags php 函数时遇到了一些问题。例如:
如果我这样做:
strip_tags("<span>some text <5ml and then >10ml some text </span>");
我会得到:
some text 10ml some text
但是,显然我想得到:
some text <5ml and then >10ml some text
是的,我知道我可以使用 <和 >,但我没有机会将这些字符转换为 html 实体,因为数据已经存储,如您在我的示例中所见。
我正在寻找的是一种解析 HTML 以便只删除实际 HTML 标记的聪明方法。
由于 TinyMCE 用于生成该数据,我知道在任何情况下都可以使用哪些实际的 html 标签,因此strip_tags($string, $black_list)
实现将比strip_tags($string, $allowable_tags)
更有用。
有什么想法吗?
【问题讨论】:
为什么你想要得到的东西很明显?<anything
是一个开始标签,因此应该被删除。所以strip_tags
正在做你要求它做的事情......
我同意 ircmaxell。你的句子有三个标签,喜欢与否。您可能需要一种不同的方法。源数据的格式是否一致?无论如何,您可以在剥离标签之前将尖括号转换为它们的 HTML 编码等效项?
@ircmaxell 和@clifgriffin:我写“显然”是因为语义上这些标志不是标签的一部分,它们的意思是“小于 5 毫升”和“大于 10 毫升”。
@ircmaxell:我并不是说 strip_tags 有错误。我正在寻求正确的方法来获得我需要的东西。
@texai:我的意思是,对于计算机而言,您的要求并不明显。这对我们任何人来说都可能是显而易见的,但没有一种编程语言能让你摆脱澄清自己想法的负担。这就是我从那条评论中的意思。
【参考方案1】:
作为一种古怪的解决方法,您可以过滤非 html 括号:
$html = preg_replace("# <(?![/a-z]) | (?<=\s)>(?![a-z]) #exi", "htmlentities('$0')", $html);
之后应用 strip_tags()。请注意,这仅适用于您的特定示例和类似情况。这是一个带有一些启发式的正则表达式,而不是人工智能来从具有其他含义的未转义尖括号中识别 html 标签。
【讨论】:
因为您已经在使用PCRE_EXTENDED
,您可以添加内联 cmets,以便我们更好地理解正则表达式。【参考方案2】:
如果你想有“大于”和“小于”的符号,你需要对它们进行转义:
&gt;
是 >
&lt;
是
参见例如这个:http://www.w3schools.com/html/html_entities.asp
【讨论】:
是的,我知道,但我没有机会将这些字符转换为 HTML 实体,因为数据已经存储,如您在我的示例中所见。我正在寻找的是一种解析 HTML 以去除实际 HTML 标签的聪明方法 @texai:好吧,你去猜测和痛苦的土地,也称为启发式;)@mario的答案在这方面看起来有点有用。【参考方案3】:不要使用strip_tags(),而是使用htmlspecialchars()。
http://php.net/manual/en/function.htmlspecialchars.php
【讨论】:
这不符合将“”替换为“”和“”替换为“”的要求 htmlspecialchars() 和 htmlentities() 只会对字符串中的内容进行编码。这不会删除任何标签。以上是关于如何以比使用 strip_tags 函数更安全的方式剥离标签?的主要内容,如果未能解决你的问题,请参考以下文章
php 使用htmlspecialchars() 和strip_tags函数过滤HTML标签的区别