0

0

PHP怎么过滤HTML标签_PHPHTML标签安全处理教程

星夢妙者

星夢妙者

发布时间:2025-09-16 10:52:01

|

572人浏览过

|

来源于php中文网

原创

答案是使用HTML Purifier等专业库结合转义与过滤策略。PHP中过滤HTML标签的核心目标是防范XSS攻击,主要手段包括strip_tags()和htmlspecialchars(),但前者无法处理危险属性如onclick,后者仅将特殊字符转义为实体,适用于纯文本输出。当需允许安全HTML时,应使用HTML Purifier等基于白名单和DOM解析的净化库,确保只保留合法标签和属性,从而在功能与安全间取得平衡。

php怎么过滤html标签_phphtml标签安全处理教程

PHP过滤HTML标签主要目标是提升安全性,尤其是防范跨站脚本(XSS)攻击。这通常通过移除或转义HTML代码来实现,具体选择哪种方式取决于你希望用户输入的内容是被完全净化为纯文本,还是允许显示部分安全的HTML标签。

解决方案

处理PHP中的HTML标签,我们通常会用到两种核心策略:过滤(Filtering)转义(Escaping)。它们的目的不同,但都是为了安全。

最基础的过滤手段是使用PHP内置的

strip_tags()
函数。这个函数能从字符串中剥去HTML、XML以及PHP标签。它接受两个参数:要处理的字符串,以及一个可选的允许保留的标签列表。

<?php
$userInput = "<p>Hello, <script>alert('XSS');</script> world!</p><a href='#' onclick='alert(\"evil\")'>Click Me</a>";

// 示例1:完全剥离所有标签
$cleanText = strip_tags($userInput);
echo "完全剥离: " . $cleanText . "\n";
// 输出: 完全剥离: Hello,  world!Click Me

// 示例2:允许保留部分标签,比如<p>和<a>
$allowedTags = '<p><a>';
$partiallyCleanText = strip_tags($userInput, $allowedTags);
echo "部分保留: " . $partiallyCleanText . "\n";
// 输出: 部分保留: <p>Hello,  world!</p><a href='#' onclick='alert("evil")'>Click Me</a>
?>

从上面的示例2可以看到,

strip_tags()
虽然移除了
<script>
标签,但它对
<a>
标签里的
onclick
属性却无能为力。这意味着,仅仅依靠
strip_tags()
来防范XSS是远远不够的。

立即学习PHP免费学习笔记(深入)”;

这时,转义就显得非常重要了。PHP的

htmlspecialchars()
htmlentities()
函数可以将HTML中的特殊字符(如
<
>
&
"
'
)转换成HTML实体。这样,即使内容中包含恶意HTML代码,浏览器也会将其作为普通文本显示,而不是执行。

<?php
$maliciousInput = "<script>alert('You are hacked!');</script>";

// 使用htmlspecialchars进行转义
$escapedInput = htmlspecialchars($maliciousInput, ENT_QUOTES, 'UTF-8');
echo "转义后的内容: " . $escapedInput . "\n";
// 输出: 转义后的内容: <script>alert(&#039;You are hacked!&#039;);</script>

// 当在HTML中显示时,浏览器会将其作为文本处理
// <p><script>alert(&#039;You are hacked!&#039;);</script></p>
?>

我个人认为,对于绝大多数需要展示用户输入的情况,

htmlspecialchars()
几乎是必备的。它能确保你显示的内容不会被浏览器误解为可执行代码。

为什么直接使用
strip_tags()
可能不够安全?

讲真,

strip_tags()
这个函数,虽然名字听起来很“安全”,但在实际的Web安全场景中,它只能算是一个初级的、甚至是有点粗暴的工具。我的经验是,如果你只是想把所有HTML标签都“一刀切”地移除,让内容变成纯文本,那它还能派上用场。但一旦你希望允许用户输入一部分安全的HTML(比如加粗、斜体),同时又想阻止恶意代码,
strip_tags()
就显得力不从心了。

它最主要的局限在于:

  1. 不处理标签属性:
    strip_tags()
    只会移除标签本身,但不会检查标签内部的属性。就像前面例子里展示的,
    <a>
    标签的
    onclick
    属性,或者
    <img>
    标签的
    onerror
    属性,这些都是XSS攻击的常见载体,
    strip_tags()
    对它们完全无感。
    <img src="nonexistent.jpg" onerror="alert('XSS via onerror');">

    这段代码经过

    strip_tags()
    处理后,
    <img>
    标签可能还在(如果你允许
    <img>
    ),但
    onerror
    属性会原封不动地保留下来,一旦浏览器加载失败,恶意脚本就会执行。

  2. 对畸形HTML的处理能力有限: HTML的解析非常复杂,浏览器对不规范的HTML有很强的容错能力。
    strip_tags()
    是一个简单的字符串匹配和移除过程,它不是一个真正的HTML解析器。这意味着,一些巧妙构造的畸形HTML,可能会绕过
    strip_tags()
    的过滤,最终在浏览器中被解析并执行。 例如,一些不完整的标签或者利用注释、CSS表达式等方式,都可能导致意外的行为。
  3. 上下文依赖的漏洞: 有时候,即使标签被移除了,恶意内容如果被插入到特定的HTML上下文(比如
    <script>
    标签内部、
    style
    属性内部),仍然可能造成危害。
    strip_tags()
    无法理解这些上下文语义。

所以,我常常强调,在处理用户输入时,安全是一个系统性的工程,不能寄希望于一个单一的函数就能解决所有问题。

strip_tags()
可以作为第一道粗略的防线,但绝不能是唯一的防线。

处理用户提交的HTML内容,应该选择过滤还是转义?

这是一个非常经典的问题,也是很多开发者容易混淆的地方。我的看法是,这并非一个“二选一”的问题,而是取决于你的具体需求和最终展示的场景。很多时候,你可能需要两者结合

让我们先明确两者的核心目的:

  • 转义(Escaping): 它的目的是将用户输入中的特殊字符(如

    <
    >
    &
    "
    '
    )转换为HTML实体,从而确保这些字符在浏览器中被当作普通文本显示,而不是被解析为HTML代码。

    • 适用场景: 当你希望用户输入的内容被原样显示,且不希望其中任何部分被浏览器解释为HTML或JavaScript时。比如,用户评论、用户名、搜索框输入等。
    • 优点: 最简单、最安全的防范XSS方法。只要你总是在输出用户数据到HTML页面时进行转义,就能有效避免绝大多数基于HTML注入的XSS。
    • 缺点: 用户无法使用任何HTML格式,比如加粗、斜体、链接等。
  • 过滤(Filtering / Sanitization): 它的目的是从用户输入中移除或净化掉所有不安全或不允许的HTML标签和属性,只留下一个经过“清洗”的、安全的HTML子集。

    触站AI
    触站AI

    专业的中文版AI绘画生成平台

    下载
    • 适用场景: 当你希望允许用户使用有限的、安全的HTML标签来格式化他们的内容时。比如,富文本编辑器(如论坛帖子、博客文章)允许用户加粗文字、插入图片或链接。
    • 优点: 提供了更好的用户体验,允许用户进行一定程度的格式化。
    • 缺点: 复杂性高,需要一个非常健壮的HTML解析器和一套完善的安全规则(通常是“白名单”机制)。如果过滤不当,很容易引入新的安全漏洞。

我的建议是:

  1. 默认情况下,始终对所有用户输出到HTML页面的数据进行转义。 这是最基本的安全实践,也是最不容易出错的。
  2. 只有当你明确需要允许用户输入并显示部分HTML时,才考虑使用过滤。 并且,在这种情况下,你绝不能仅仅依靠
    strip_tags()
    ,而应该使用专业的HTML净化库。

可以这样理解:转义是你的“安全网”,确保任何意外的或恶意的HTML代码都不会被执行。而过滤,是在你决定让用户“走钢丝”(允许部分HTML)时,为这条钢丝搭建的坚固“防护栏”。两者结合,才能在安全性和功能性之间找到平衡。

有哪些更可靠的PHP库或方法来安全处理HTML内容?

strip_tags()
htmlspecialchars()
不足以满足你的需求,特别是当你需要允许用户提交部分HTML内容时,你就需要更专业、更强大的工具了。我个人在处理这类问题时,会毫不犹豫地推荐使用专门的HTML净化库。其中,
HTML Purifier
无疑是PHP生态中最值得信赖的选择。

1. HTML Purifier

HTML Purifier
被广泛认为是PHP中处理HTML内容的“黄金标准”。它不是简单地移除黑名单上的标签或属性,而是采用严格的“白名单”策略,根据W3C标准来解析和净化HTML。这意味着,它只会允许明确定义为安全的标签和属性,所有其他不符合规范或潜在危险的内容都会被移除或纠正。

为什么它如此可靠?

  • 基于W3C标准: 它使用一个完整的DOM解析器来理解HTML结构,而不是简单的正则表达式匹配,这使得它能够正确处理各种复杂、畸形或嵌套的HTML。
  • 白名单机制: 默认只允许一小部分已知的安全标签和属性。你可以根据自己的需求扩展这个白名单,但它的核心是“只允许你明确允许的”。
  • 修复畸形HTML: 它不仅能移除恶意代码,还能尝试修复一些不规范的HTML结构,使其变得有效且安全。
  • 持续维护和更新: 作为一个成熟的开源项目,它有专门的团队维护,能够及时应对新的安全威胁。

基本使用示例:

首先,你需要通过Composer安装它:

composer require ezyang/htmlpurifier

然后,在你的PHP代码中:

<?php
require_once '/path/to/vendor/autoload.php'; // 根据你的Composer安装路径调整

$config = HTMLPurifier_Config::createDefault();
// 你可以根据需求配置允许的标签、属性等
// 例如,允许<a>标签和其href、title属性
// $config->set('HTML.Allowed', 'p,a[href|title],strong,em');
// 允许所有默认安全的HTML标签和属性
// $config->set('HTML.AllowedElements', array('p', 'a', 'strong', 'em', 'ul', 'ol', 'li', 'br', 'img'));
// $config->set('HTML.AllowedAttributes', array('a.href', 'a.title', 'img.src', 'img.alt'));

$purifier = new HTMLPurifier($config);

$dirty_html = '<p>Hello, <script>alert("XSS");</script> world!</p><a href="javascript:alert(\'evil\')">Click Me</a><img src="x" onerror="alert(\'more evil\')">';
$clean_html = $purifier->purify($dirty_html);

echo "原始HTML:\n" . $dirty_html . "\n\n";
echo "净化后HTML:\n" . $clean_html . "\n";
?>

运行上述代码,你会看到

<script>
标签、
<a>
标签的
javascript:
协议链接以及
<img>
标签的
onerror
属性都被安全地移除了,只保留了安全的HTML结构。这才是真正可靠的HTML净化。

2. DOMDocument (自定义解析)

对于一些非常特殊的需求,或者当你需要对HTML结构进行更细粒度的控制时,PHP内置的

DOMDocument
类也是一个强大的工具。它允许你将HTML字符串解析成一个DOM树,然后你可以遍历这个树,手动检查、修改或移除节点和属性。

优点: 提供了极高的灵活性和控制力。 缺点: 实现起来相对复杂,需要对DOM操作有深入的理解,而且你自己编写的净化逻辑需要经过严格的安全审查,否则很容易引入新的漏洞。它不适合新手,也不建议作为通用解决方案。

示例(非常简略,仅作概念说明):

<?php
$html = '<p>Hello, <script>alert("XSS");</script> <a href="http://example.com" onclick="alert(\'evil\')">Link</a></p>';

$dom = new DOMDocument();
// 抑制HTML解析错误
@$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

$xpath = new DOMXPath($dom);

// 移除所有script标签
foreach ($xpath->query('//script') as $node) {
    $node->parentNode->removeChild($node);
}

// 移除所有元素的onclick属性
foreach ($xpath->query('//*[@onclick]') as $node) {
    $node->removeAttribute('onclick');
}

// 进一步可以遍历所有标签,只保留白名单中的标签和属性

$cleanHtml = $dom->saveHTML();
echo $cleanHtml;
?>

使用

DOMDocument
来做净化工作,你需要非常小心地定义你的白名单规则,并确保覆盖所有可能的攻击向量。

总而言之,如果你需要处理用户提交的HTML内容并确保其安全性,我的建议是:优先使用HTML Purifier。它久经考验,提供了最全面的安全保障。只有在极少数极端定制化的场景下,并且你对Web安全和DOM操作有足够的信心时,才考虑自己基于

DOMDocument
实现净化逻辑。记住,安全无小事,宁可保守,不可冒险。

相关文章

HTML速学教程(入门课程)
HTML速学教程(入门课程)

HTML怎么学习?HTML怎么入门?HTML在哪学?HTML怎么学才快?不用担心,这里为大家提供了HTML速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
composer是什么插件
composer是什么插件

Composer是一个PHP的依赖管理工具,它可以帮助开发者在PHP项目中管理和安装依赖的库文件。Composer通过一个中央化的存储库来管理所有的依赖库文件,这个存储库包含了各种可用的依赖库的信息和版本信息。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

162

2023.12.25

js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

531

2023.06.20

正则表达式不包含
正则表达式不包含

正则表达式,又称规则表达式,,是一种文本模式,包括普通字符和特殊字符,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式的文本。php中文网给大家带来了有关正则表达式的相关教程以及文章,希望对大家能有所帮助。

258

2023.07.05

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

766

2023.07.05

java正则表达式匹配字符串
java正则表达式匹配字符串

在Java中,我们可以使用正则表达式来匹配字符串。本专题为大家带来java正则表达式匹配字符串的相关内容,帮助大家解决问题。

219

2023.08.11

正则表达式空格
正则表达式空格

正则表达式空格可以用“s”来表示,它是一个特殊的元字符,用于匹配任意空白字符,包括空格、制表符、换行符等。本专题为大家提供正则表达式相关的文章、下载、课程内容,供大家免费下载体验。

357

2023.08.31

Python爬虫获取数据的方法
Python爬虫获取数据的方法

Python爬虫可以通过请求库发送HTTP请求、解析库解析HTML、正则表达式提取数据,或使用数据抓取框架来获取数据。更多关于Python爬虫相关知识。详情阅读本专题下面的文章。php中文网欢迎大家前来学习。

293

2023.11.13

正则表达式空格如何表示
正则表达式空格如何表示

正则表达式空格可以用“s”来表示,它是一个特殊的元字符,用于匹配任意空白字符,包括空格、制表符、换行符等。想了解更多正则表达式空格怎么表示的内容,可以访问下面的文章。

245

2023.11.17

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

37

2026.03.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.9万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

CSS教程
CSS教程

共754课时 | 42.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号