html解析器遇c0控制字符会抛异常或构建空dom,清洗必须在loadhtml()前完成:启用libxml错误抑制、正则清除非法字符、必要时转码,strip_tags等无效,unicode不间断空格需特殊处理。

HTML解析器遇到 \x00–\x08、\x0B、\x0C、\x0E–\x1F 这类 C0 控制字符时,**不会静默跳过,而是直接抛出异常或构建空 DOM**——清洗必须在 loadHTML() 之前完成,没有例外。
DOMDocument::loadHTML() 前必须做三件事
PHP 的 DOMDocument 对控制字符极其敏感,\x00 会截断字符串,\x0C 可能干扰 libxml 解析边界:
- 先调用
libxml_use_internal_errors(true),否则\x00导致整个脚本 fatal error - 用
preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F]/u', '', $html)清洗——注意保留\x09(tab)、\x0A(LF)、\x0D(CR) - 若来源是 MySQL 或旧系统,加一层
mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'),它能同时修复乱码字节和替换不可见控制符
html5-php 中 parseError 不等于可恢复
你可能想用 html5-php 的 EventHandler::parseError() 捕获 token 错误,但实际效果有限:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 底层
Tokenizer遇到\x01这类字符会直接 throwParseException,无法继续解析 - 即使实现
parseError(),也只记录错误位置,不能“跳过并继续”——DOM 已中断,$dom->find('p')返回空数组是常态 - 真正可靠的路径仍是:预清洗 → 再传入
str_get_html()
strip_tags() 和 htmlspecialchars() 完全无效
这两个函数常被误用作“兜底”,但它们根本没机会执行:
-
strip_tags("\x00<div>test</div>")返回空字符串——因为\x00让 PHP 字符串提前终止,strip_tags()收到的是空输入 -
htmlspecialchars("\x01<script>alert(1)</script>")确实输出转义后的 HTML,但浏览器不会渲染;问题不在 XSS,而在原始字符串根本无法被解析成 DOM 节点 - 静默失败比报错更危险:你调
$dom->find('img')得到空数组,却不知道是因为控制字符阻断了解析
Unicode 不间断空格 u+00a0 的特殊处理
它不属于 C0 控制字符,但同样导致文本比较失效、XPath 匹配失败:
-
" "解析后变成 Unicode 字符\u{00a0},不是普通空格\x20 - 别用
str_replace(" ", "", $text)或chr(160)—— UTF-8 下chr(160)是单字节,而\u{00a0}是双字节\xC2\xA0 - PHP 7.0+ 正确写法:
str_replace("\u{00a0}", " ", $text),或正则preg_replace('/\u{00a0}/u', ' ', $text)
最易被忽略的点:控制字符常藏在用户粘贴内容、爬虫抓取的乱码页面、数据库字段未清理的场景里,且往往不报错——只让 find() 返回空。清洗动作必须无条件前置,不能靠“试试看”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










