用PHP中的htmlspecialchars()替换除某些html标签外的所有HTML标签?

我想处理我的用户输入,以仅允许某些html标记,并用其html实体替换其他标记,以及替换非标记字符.例如,如果我只想允许< b>和< a>标签,然后

allow_only("This is <b>bold</b> and this is <i>italic</i>.
            Moreover 2<3 and <a href='google.com'>this is a link</a>.","<b><a>");

应该产生

This is <b>bold</b> and this is &lt;i&gt;italic&lt;/i&gt;.
Moreover 2&lt;3 and <a href='google.com'>this is a link</a>.

如何在PHP中做到这一点?我知道strip_tags()可以完全删除不需要的标签,并且我知道htmlspecialchars()可以用其html实体替换所有标签,但是不能替换只有特定标签的地方.如何在PHP中完成?

而且,如果没有“通用”方式来执行此操作,那么通常我应该如何继续处理可以具有有效常规html但也可以具有<标志和潜在危险的html代码?

解决方法:

应用htmlspecialchars,然后将给定标签数组的编码实体替换为常规实体

function allow_only($str, $allowed){
    $str = htmlspecialchars($str);
    foreach( $allowed as $a ){
        $str = str_replace("&lt;".$a."&gt;", "<".$a.">", $str);
        $str = str_replace("&lt;/".$a."&gt;", "</".$a.">", $str);
    }
    return $str;
}
echo allow_only("This is <b>bold</b> and this is <i>italic</i>.", array("b"));

这适用于简单的标签,返回“这是粗体字,这是< i®< / i>”.

如前所述,这不适用于带有属性的标签,但是可以:

function fix_attributes($match){
    return "<".$match[1].str_replace('&quot;','"',$match[2]).">";
}
function allow_only($str, $allowed){
    $str = htmlspecialchars($str);
    foreach( $allowed as $a ){
        $str = preg_replace_callback("/&lt;(".$a."){1}([\s\/\.\w=&;:#]*?)&gt;/", fix_attributes, $str);
        $str = str_replace("&lt;/".$a."&gt;", "</".$a.">", $str);
    }
    return $str;
}
echo allow_only('This is <b>bold</b> and <a href="http://www.#links">this</a> is <i>italic</i>.', array("b","a"));

使用某些属性处理更复杂的标签,因此只允许[]之间列出的字符出现在属性中.不幸的是& quot;必须在属性中允许它,否则它将不起作用,并且也允许所有其他实体使用-但是仅对属性中的& quot进行解码.

正如建议的那样,使用像http://htmlpurifier.org/demo.php这样的库是解决这种问题的更好(更安全,更干净)的方法

上一篇:PHP htmlspecialchars错误


下一篇:如何在php的htmlspecialchars中转换新行和html代码