<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-comment">// 本文档演示如何更好地使用 mb_encode_numericentity 搭配 htmlentities 进行字符编码处理</span></span><span>
</span><span><span class="hljs-comment">// 用于 PHP 环境下处理多字节字符时避免乱码或信息丢失问题</span></span><span>
</span><span><span class="hljs-comment">// ----------------------------</span></span><span>
<span class="hljs-comment">/**
* 如何更好地使用 mb_encode_numericentity 搭配 htmlentities 进行字符编码处理?
*
* 在处理包含非 ASCII 字符的多语言内容(如中文、日文、韩文等)时,PHP 的 `htmlentities` 函数常用于将特殊字符转换为 HTML 实体,以避免 XSS 等安全问题。
* 然而,`htmlentities` 对多字节字符的支持有限,尤其当字符集设为 UTF-8 时,部分字符可能会被直接忽略或转义不完整。
*
* 为了解决这一问题,`mb_encode_numericentity` 可以配合 `htmlentities` 使用,将非 ASCII 字符先转换为数字实体,再统一进行 HTML 转义。
* 下面我们通过实际示例来讲解这一流程。
*
* 一、基本用法示例
*/</span>
</span><span><span class="hljs-variable">$input</span></span><span> = </span><span><span class="hljs-string">"你好,世界!<script>alert('XSS');</script>"</span></span><span>;
</span><span><span class="hljs-variable">$encoding</span></span><span> = </span><span><span class="hljs-string">'UTF-8'</span></span><span>;
</span><span><span class="hljs-comment">// 定义实体转换范围(0x80 到 0xFFFF 表示所有非 ASCII 字符)</span></span><span>
</span><span><span class="hljs-variable">$convmap</span></span><span> = [</span><span><span class="hljs-number">0x80</span></span><span>, </span><span><span class="hljs-number">0xffff</span></span><span>, </span><span><span class="hljs-number">0</span></span><span>, </span><span><span class="hljs-number">0xffff</span></span><span>];
</span><span><span class="hljs-comment">// 第一步:将非 ASCII 字符转换为数字实体</span></span><span>
</span><span><span class="hljs-variable">$numericEntity</span></span><span> = </span><span><span class="hljs-title function_ invoke__">mb_encode_numericentity</span></span><span>(</span><span><span class="hljs-variable">$input</span></span><span>, </span><span><span class="hljs-variable">$convmap</span></span><span>, </span><span><span class="hljs-variable">$encoding</span></span><span>);
</span><span><span class="hljs-comment">// 第二步:将剩余内容转义为 HTML 实体(如 < > & 等符号)</span></span><span>
</span><span><span class="hljs-variable">$escapedOutput</span></span><span> = </span><span><span class="hljs-title function_ invoke__">htmlentities</span></span><span>(</span><span><span class="hljs-variable">$numericEntity</span></span><span>, ENT_QUOTES | ENT_HTML5, </span><span><span class="hljs-variable">$encoding</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-variable">$escapedOutput</span></span><span>;
<span class="hljs-comment">/**
* 输出结果类似于:
* &#20320;&#22909;&#65292;&#19990;&#30028;&#65281;&lt;script&gt;alert(&#039;XSS&#039;);&lt;/script&gt;
*
* 可见,“你好,世界!” 中的中文字符已被转换为十进制 HTML 实体,而脚本标签与引号等特殊字符也被成功转义。
*
* 二、为何这样做?
*
* - **增强兼容性**:htmlentities 在遇到非 ISO-8859-1 编码字符时行为不一,配合 mb_encode_numericentity 可确保所有字符都被显式处理;
* - **提高安全性**:XSS 攻击常通过注入 HTML 标签或 JavaScript 来实现,提前转义所有可疑字符可大大降低风险;
* - **避免乱码**:在输出到网页、日志、或数据库时,多字节字符如果未正确转义可能被误解释,从而出现乱码或数据异常。
*
* 三、注意事项
*
* 1. `mb_encode_numericentity` 要在 `htmlentities` **之前** 调用,否则非 ASCII 字符可能会被提前截断或忽略。
* 2. `convmap` 的设置要覆盖目标字符的 Unicode 范围,常用配置如 `[0x80, 0xffff, 0, 0xffff]` 足以覆盖绝大部分 UTF-8 字符。
* 3. 若处理 HTML 输入内容(例如用户提交的富文本),建议配合 `html_entity_decode` 与 `mb_decode_numericentity` 实现双向转码。
*
* 四、结语
*
* 结合使用 `mb_encode_numericentity` 与 `htmlentities` 能更安全、可靠地处理多语言环境下的字符编码问题。
* 在处理任何用户输入、动态文本、或输出至浏览器前,强烈建议进行此类转义处理,以确保应用的稳定性与安全性。
*/</span>
</span><span><span class="hljs-meta">?></span></span><span>
</span></span>