净化 HTML 输入和输出
最后更新于:2022-04-01 21:14:07
## 对于简单的数据净化,使用 [htmlentities()](http://php.net/manual/zh/function.htmlentities.php) 函数, 复杂的数据净化则使用[HTML Purifier](http://htmlpurifier.org/) 库
**经 HTML Purifier 4.4.0 测试**
在任何 wbe 应用中展示用户输出时,首先对其进行“净化”去除任何潜在危险的 HTML 是非常必要的。 一个恶意的用户可以制作某些 HTML,若被你的 web 应用直接输出,对查看它的人来说会很危险。
虽然可以尝试使用正则表达式来净化 HTML,但不要这样做。HTML是一种复杂的语言,试图使用正则表达式来净化 HTML 几乎总是失败的。
你可能会找到建议你使用 [strip_tags()](http://php.net/manual/zh/function.strip-tags.php) 函数的观点。 虽然 strip_tags() 从技术上来说是安全的,但如果输入的不合法的 HTML(比如, 没有结束标签),它就成了一个「愚蠢」的函数,可能会去除比你期望的更多的内容。 由于非技术用户在通信中经常使用`<` 和` >` 字符,`strip_tags()` 也就不是一个好的选择了。
如果阅读了[验证邮件地址](http://phpbestpractices.justjavac.com/#validating-emails)一节, 你也许也会考虑使用 [filter_var()](http://php.net/manual/zh/function.filter-var.php) 函数。 然而 [filter_var() 函数在遇到断行时会出现问题](http://stackoverflow.com/questions/3150413/filter-sanitize-special-chars-problem-with-line-breaks), 并且需要不直观的配置以接近 [htmlentities()](http://php.net/manual/zh/function.htmlentities.php) 函数的效果, 因此也不是一个好的选择。
## 对于简单需求的净化
如果你的 web 应用仅需要完全地转义(因此可以无害地呈现,但不是完全去除) HTML, 则使用 PHP 的内建[htmlentities()](http://php.net/manual/zh/function.htmlentities.php) 函数。 这个函数要比 HTML Purifier 快得多,因此它不对 HTML 做任何验证---仅转义所有东西。
htmlentities() 不同于类似功能的函数[htmlspecialchars()](http://php.net/manual/zh/function.htmlspecialchars.php), 它会编码所有适用的 HTML 实体,而不仅仅是一个小的子集。
### 示例
~~~
Mua-ha-ha! Twiddling my evil mustache...
';
// Use the ENT_QUOTES flag to make sure both single and double quotes are escaped.
// Use the UTF-8 character encoding if you've stored the text as UTF-8 (as you should have).
// See the UTF-8 section in this document for more details.
$safeHtml = htmlentities($evilHtml, ENT_QUOTES, 'UTF-8');
// $safeHtml is now fully escaped HTML. You can output $safeHtml to your users without fear!
?>
~~~
## 对于复杂需求的净化
对于很多 web 应用来说,简单地转义 HTML 是不够的。 你可能想完全去除任何HTML,或者允许一小部分子集的 HTML 存在。 若是如此,则使用 [HTML Purifier](http://htmlpurifier.org/) 库。
HTML Purifier 是一个经过充分测试但效率比较低的库。 这就是为什么如果你的需求并不复杂就应使用[htmlentities()](http://php.net/manual/zh/function.htmlentities.php), 因为它的效率要快得多。
HTML Purifier 相比 [strip_tags()](http://php.net/manual/zh/function.strip-tags.php) 是有优势的, 因为它在净化 HTML 之前会对其校验。 这意味着如果用户输入无效 HTML,HTML Purifier 相比 strip_tags() 更能保留 HTML 的原意。 HTML Purifier 高度可定制,允许你为 HTML 的一个子集建立白名单来允许这个 HTML 子集的实体存在输出中。
但其缺点就是相当的慢,它要求一些设置,在一个共享主机的环境里可能是不可行的。 其文档通常也复杂而不易理解。 以下示例是一个基本的使用配置。 查看[文档](http://htmlpurifier.org/docs)阅读 HTML Purifier 提供的更多更高级的特性。
### 示例
~~~
Mua-ha-ha! Twiddling my evil mustache...