繁体   English   中英

我如何使用 htmlspecialchars 但只允许特定的 HTML 代码通过而不被转换?

[英]How Do I use htmlspecialchars but allow only specific HTML code to pass through without getting converted?

这是我的代码行,效果很好:

$content = htmlspecialchars($_POST['content'], ENT_QUOTES);

但我想做的是只允许某些类型的 HTML 代码通过而不被转换。 这是我想要传递的 HTML 代码列表:

<pre> </pre>
<b> </b>
<em> </em>
<u> </u>
<ul> </ul>
<li> </li>
<ol> </ol>

当我走的时候,我也希望能够在以后添加更多的 HTML。 有人可以帮我修改上面的代码,以便上面指定的 HTML 代码列表可以通过而不被转换吗?

我想你可以在事后做到这一点:

// $str is the result of htmlspecialchars()
preg_replace('#&lt;(/?(?:pre|b|em|u|ul|li|ol))&gt;#', '<\1>', $str);

它允许<xx></xx>的编码版本,其中xx位于一组受控的允许标签中。

或者您可以使用旧样式:

$content = htmlspecialchars($_POST['content'], ENT_QUOTES);

$turned = array( '&lt;pre&gt;', '&lt;/pre&gt;', '&lt;b&gt;', '&lt;/b&gt;', '&lt;em&gt;', '&lt;/em&gt;', '&lt;u&gt;', '&lt;/u&gt;', '&lt;ul&gt;', '&lt;/ul&gt;', '&lt;li&gt;', '&lt;/li&gt;', '&lt;ol&gt;', '&lt;/ol&gt;' );
$turn_back = array( '<pre>', '</pre>', '<b>', '</b>', '<em>', '</em>', '<u>', '</u>', '<ul>', '</ul>', '<li>', '</li>', '<ol>', '</ol>' );

$content = str_replace( $turned, $turn_back, $content );

我改进了杰克解决这个问题的方式。 我添加了对<br>, <br/>和锚标记的支持。 该代码将替换 fist href=&quot;...&quot; 只允许使用此属性。

$str = preg_replace(
    array('#href=&quot;(.*)&quot;#', '#&lt;(/?(?:pre|a|b|br|em|u|ul|li|ol)(\shref=".*")?/?)&gt;#' ), 
    array( 'href="\1"', '<\1>' ), 
    $str
);

我喜欢 Elwin 的解决方案,但您可能想要:

  1. 防止 Javascript: URL 在href - 或者更有可能:仅允许http(s)
  2. 如果内容中有多个<a href>请使正则表达式不贪婪。

这是更新的版本:

$str = preg_replace(
    array('#href=&quot;(https?://.*?)&quot;#', '#&lt;(/?(?:pre|a|b|br|em|u|ul|li|ol)(\shref=".*?")?/?)&gt;#' ), 
    array( 'href="\1"', '<\1>' ), 
    $str
);

我创建了这个函数来清理除指定的 HTML 标签之外的所有 HTML 特殊字符。

它首先使用 htmlspecialchars() 使字符串安全,然后恢复我想要保持不变的标签。

该功能支持属性过滤作为一个选项,但是如果您关心可能的 XSS 攻击,请小心禁用它。

我知道正则表达式效率不高,但对于中等长度的字符串应该没问题。 您可以检查我在这里使用的正则表达式https://regex101.com/r/U6GQse/8

public function sanitizeHtml($string, $safeHtmlTags = array('b','i','u','br'), $filterAttributes = true)
{
    $string = htmlspecialchars($string);

    if ($filterAttributes) {
        $replace = "<$1$2$4>";
    } else {
        $replace = "<$1$2$3$4>";
    }
    $string = preg_replace("/&lt;\s*(\/?\s*)(".implode("|", $safeHtmlTags).")(\s?|\s+[\s\S]*?)(\/)?\s*&gt;/", $replace, $string);

    return $string;
}

// Example usage to answer the OP question
$str = "MY HTML CONTENT"
echo sanitizeHtml($str, array('pre','b','em','u','ul','li','ol'));

你可以使用strip_tags

$exceptionString = '<pre>,</pre>,<b>,</b>,<em>,</em>,<u>,</u>,<ul>,</ul>,<li>,</li>,<ol>,</ol>';

$content = strip_tags($_POST['content'],$exceptionString );

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM