htmlspecialchars默认转义&、<、>、"、'五个字符,分别对应&、<、>、"、'实体;其中单引号仅在指定ENT_QUOTES时才转义,且不处理空格、中文、emoji等其他字符。

htmlspecialchars 会把哪些字符转义
htmlspecialchars 默认只转义 5 个关键字符:&、、<code>>、"、'。它不会动空格、换行、中文或其它符号——这点常被误以为“没生效”,其实是预期行为。
常见错误现象:页面里中文正常显示,但 © 变成 ©,或者用户输入的 <script></script> 被干掉了一半——这说明它起作用了,只是没覆盖你想象中的全部范围。
- 默认只处理双引号
",单引号'不转(除非显式传ENT_QUOTES) - 不处理 Unicode 字符、emoji、全角标点,这些得靠其他手段(比如输出前统一 UTF-8 编码检查)
- 如果源字符串本身是 HTML 实体(如
<),它不会“二次解码再转”,而是原样当普通文本处理
第三个参数 $encoding 必须填吗
PHP 5.4+ 默认用 UTF-8,但老项目或非标准环境(比如 ISO-8859-1 页面)下不指定 $encoding,可能触发警告甚至乱码。不是“可选”,而是“必须和你的实际字符集一致”。
使用场景:你用 mb_internal_encoding('GBK'),但没在 htmlspecialchars 里写 'GBK',那中文引号、破折号就可能变成 。
立即学习“PHP免费学习笔记(深入)”;
- 现代项目一律显式写
htmlspecialchars($str, ENT_QUOTES, 'UTF-8') - 若不确定页面编码,先查
mb_http_output()或响应头Content-Type - 传错编码不会报错,只会静默出错——这是最危险的地方
ENT_QUOTES 和 ENT_HTML5 有什么区别
ENT_QUOTES 控制是否转义单引号;ENT_HTML5 控制解析模式,影响对 、' 等实体的识别逻辑。两者可同时用,但目的完全不同。
性能影响极小,但语义差异明显:不加 ENT_QUOTES,你在 value='=$name?>' 里输出用户输入的 O'Reilly 就会直接 break HTML;不用 ENT_HTML5,某些新 HTML5 实体(如 &x27;)可能不被识别为合法字符而保留原样。
- 表单字段值建议组合:
htmlspecialchars($str, ENT_QUOTES | ENT_HTML5, 'UTF-8') -
ENT_COMPAT(默认)只转双引号,ENT_NOQUOTES一个都不转——基本不用 -
ENT_SUBSTITUTE可让非法字节替换成 ,避免空白或截断,适合处理脏数据
为什么用了 htmlspecialchars 还有 XSS
因为 htmlspecialchars 只解决“HTML 上下文”里的注入,它不管 JavaScript 字符串、CSS 属性、URL 参数、HTML 注释等其它上下文。这是最常被忽略的复杂点。
典型错误:把用户输入拼进 <script>var name = "<?=htmlspecialchars($name)?>";</script> ——双引号被转了,但换行或 \ 仍能逃逸;或者放进 href="javascript:..." 里,根本没进 HTML 文本节点。
- JS 内联变量要用
json_encode($str, JSON_HEX_TAG | JSON_HEX_AMP),不是htmlspecialchars - URL 参数要用
urlencode(),属性值含 URL 时还要额外htmlspecialchars(..., ENT_QUOTES) - 富文本场景不能依赖它——该用
HTMLPurifier或DOMDocument白名单过滤



















