PHP安全过滤HTML标签应优先使用HTMLPurifier实现白名单式过滤,strip_tags()仅适用于纯文本场景且存在绕过风险,手动正则过滤极易被大小写混淆、编码或注释干扰绕过,不推荐用于用户输入。

PHP接收参数时如何安全过滤HTML标签
直接用 htmlspecialchars() 或 htmlentities() 并不能满足「保留部分HTML但剔除危险标签」的需求。真正需要的是白名单式过滤,而非简单转义。
用 strip_tags() 去掉所有HTML但保留换行和空格
这是最轻量的方案,适用于纯文本输入场景(如评论、简介),但会无差别删掉所有标签,包括 、 等无害标签。
-
strip_tags()第二个参数可传入允许的标签数组,例如:strip_tags($input, ['', '
', '']) - 注意:它不解析嵌套或闭合关系,
即使被写成也可能绕过,不能用于高危输入 - 对含属性的标签无效,比如
中的href属性不会被检查,仅标签名被比对
用 HTMLPurifier 实现严格白名单过滤
这是目前 PHP 生态中唯一被广泛验证、支持完整 HTML5 规范且可配置 XSS 防护的方案。它会解析 DOM、校验属性、清理事件处理器和危险协议。
- 安装:
composer require ezyang/htmlpurifier - 基础用法:
$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.Allowed', 'p,b,i,a[href|title],br,ul,ol,li');
$purifier = new HTMLPurifier($config);
$clean_html = $purifier->purify($_POST['content']);- 关键配置项:
URI.AllowedSchemes控制哪些协议可用(默认只留http、https、mailto);HTML.SafeIframe开启后才允许,且需配合HTML.SafeIframe.Regexp限定来源 - 性能开销明显高于
strip_tags(),建议对高频接口做缓存或异步净化
手动正则过滤存在严重风险,不推荐
用 preg_replace() 匹配 或 on\w+= 类模式看似简单,但极易被绕过:
立即学习“PHP免费学习笔记(深入)”;
除非你明确知道输入来源绝对可控(如后台管理员富文本编辑器导出内容),否则不要依赖正则清洗用户提交的 HTML。
HTML 过滤的核心矛盾在于:既要保留排版能力,又要杜绝执行能力。没有银弹,strip_tags() 适合低交互场景,HTMLPurifier 是通用解,而任何试图“自己写一个更轻的过滤器”的尝试,大概率会在某次上线后触发 XSS 漏洞。











