PHP安全过滤HTML标签应优先使用HTMLPurifier实现白名单式过滤,strip_tags()仅适用于纯文本场景且存在绕过风险,手动正则过滤极易被大小写混淆、编码或注释干扰绕过,不推荐用于用户输入。
直接用 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+= 类模式看似简单,但极易被绕过:
、
、
除非你明确知道输入来源绝对可控(如后台管理员富文本编辑器导出内容),否则不要依赖正则清洗用户提交的 HTML。
HTML 过滤的核心矛盾在于:既要保留排版能力,又要杜绝执行能力。没有银弹,strip_tags() 适合低交互场景,HTMLPurifier 是通用解,而任何试图“自己写一个更轻的过滤器”的尝试,大概率会在某次上线后触发 XSS 漏洞。