
本文介绍使用 PHP 的 DOMDocument 和 DOMXPath 安全、可靠地过滤 HTML 属性,仅保留 id 和 class 等指定属性,避免正则表达式解析 HTML 带来的不可靠性与维护难题。
本文介绍使用 php 的 domdocument 和 domxpath 安全、可靠地过滤 html 属性,仅保留 `id` 和 `class` 等指定属性,避免正则表达式解析 html 带来的不可靠性与维护难题。
在 Web 开发中,常需对用户提交或第三方来源的 HTML 进行净化处理,例如仅允许
因此,推荐采用基于标准 HTML 解析器的方案:PHP 内置的 DOMDocument 类配合 DOMXPath 或原生 DOM 遍历。它能准确识别文档结构、属性命名与值边界,且天然支持大小写不敏感、多种引号格式及 HTML5 自定义属性。
以下为推荐实现(使用 getElementsByTagName('*'),简洁高效,无需 XPath):
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
$html = '<div id="one-id" class="someClassName">Some text <a href="#" title="Words" id="linkId" class="classLink" data-foo="bar">link</a> with only the class and id attributes.</div>';
$dom = new DOMDocument();
// 关键:禁用自动添加 包裹,避免污染输出
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
// 遍历所有元素节点(* 表示任意标签)
foreach ($dom->getElementsByTagName('*') as $node) {
// 逆序遍历属性(因 removeAttribute() 会改变 attributes 集合长度)
for ($i = $node->attributes->length - 1; $i >= 0; $i--) {
$attr = $node->attributes->item($i);
// 白名单检查:只保留 'id' 和 'class'
if (!in_array($attr->name, ['id', 'class'], true)) {
$node->removeAttribute($attr->name);
}
}
}
// 输出净化后的 HTML(不含 和 )
echo $dom->saveHTML();
✅ 输出结果:
<div id="one-id" class="someClassName">Some text <a id="linkId" class="classLink">link</a> with only the class and id attributes.</div>
注意事项:
- LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD 是关键选项:防止 loadHTML() 自动补全 、 和 ,确保输出纯净;
- 必须逆序遍历属性($i--),否则删除属性后索引错位,导致部分属性被跳过;
- in_array(..., true) 启用严格比较,避免 id 与 data-id 等名称误匹配;
- 如需扩展白名单(如增加 data-* 属性),可改用正则判断:!preg_match('/^(id|class|data-.+)$/i', $attr->name);
- 若需保留空格/换行格式,可在 saveHTML() 前调用 $dom->preserveWhiteSpace = true;,但通常建议后续用 HTML Tidy 或 minify 工具统一处理。
总结:面对 HTML 属性过滤任务,应坚决放弃正则表达式方案——它看似简短,实则脆弱、难调试、不可扩展。而 DOMDocument 方案虽代码略长,却具备语义准确性、可维护性与安全性,是生产环境的标准实践。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










