HTMLPurifier 让 p 标签可以包含 video, audio 等标签
默认情况下HTMLPurifier 会将
<p>
<video>...</video>
</p>
转换为:
<p></p>
<video>...</video>
这样,<video> 被移到了 <p> 标签外
HTML Purifier 的默认定义更偏旧(主要围绕 HTML 4.01 / XHTML 1.x 的元素与内容模型)。在这种情况下,如果你在净化时允许了一些 HTML5 标签/属性(例如 video、audio、source、picture、figure、section,以及一些 HTML5 的全局属性等),纯用原生 HTML Purifier 可能会:
把不认识的标签当成不允许的内容而移除;
移除它不认识或不在白名单定义里的属性;
或者在修复结构时表现得更“保守”
在 HTML 标准中,<p> 标签不允许包含块级元素,例如 <div>。HTMLPurifier 会自动修复不符合 HTML 规范的结构,确保生成符合 W3C 标准的 HTML。
自动闭合机制 (Auto-closing),这是浏览器和解析器处理 HTML 的底层逻辑:
解析到
<p>: 开启一个段落上下文。解析到
<video>: 解析器认为:“嘿,段落里不应该放这个大家伙。”触发修正: 解析器在
<video>之前自动插入一个</p>来结束段落。结果: 变成了
<p></p><video>...</video>。
虽然在 HTML5 标准中,<video> 的地位有点特殊(它被称为“透明内容模型”),但 HTMLPurifier 底层是用到 PHP dom 扩展,其中 DOMDocument::loadHTML 只支持HTML4:
Warning
Use Dom\HTMLDocument to parse and process modern HTML instead of DOMDocument.
This function parses the input using an HTML 4 parser. The parsing rules of HTML 5, which is what modern web browsers use, are different. Depending on the input this might result in a different DOM structure. Therefore this function cannot be safely used for sanitizing HTML.
PHP手册上说到 解析html5可能导致生成不同的DOM结构。
其中的一个解决办法是安装这个包
https://packagist.org/packages/xemlock/htmlpurifier-html5
这个包在原来包的基础上扩展了对HTML5的支持,我测试过可行。
htmlpurifier-html5 的作用是:
注册 HTML5 的元素定义(Element definitions)
让 Purifier “认识”<video>,<audio>,<source>等标签。补充允许的属性/属性集合(Attributes)
例如controls,poster,preload,playsinline等(实际取决于该包具体实现)。有些实现还会 补充内容模型/子元素规则(例如
video里面允许source、track等)。
它并不是一个新的 purifier 引擎,而是 对 HTML Purifier 的 HTML 定义层做扩展,让你在“白名单净化”时更好地支持 HTML5。
如果你不想把所有HTML5标签牵扯进来,仅仅是希望 <p> 能包含 <video>,<audio>等
// 允许 p 标签包含其他标签作为块级元素,例如 video/audio 标签作
$def->addElement(
'p', // 元素名
'Block', // 类型:块级元素
'Flow', // 内容模型:流式内容 https://developer.mozilla.org/en-US/docs/Web/HTML/Guides/Content_categories#flow_content
'Flow', // 内容模型类型:流式内容
null // 允许的子元素:无指定,可以包含任何元素
)