← PHP hex2bin()十六进制转ASCII字符函数详解 PHP html_entity_decode()函数:HTML实体还原字符教程 →

PHP htmlentities()函数:字符转HTML实体教程

著
原创 2026-10-10 PHP 已有人查阅

一、函数定位与核心作用

htmlentities()是PHP的字符串处理函数,用于把字符串中所有具有对应HTML实体的字符转换成实体形式。所谓HTML实体,是指用&...;这样的转义序列表示特殊字符,比如<变成&lt;,>变成&gt;,&变成&amp;。

它和htmlspecialchars()经常被放在一起比较。区别在于:htmlspecialchars()只转换少数几个对HTML有语法意义的字符,而htmlentities()会转换所有能匹配到实体的字符,范围更广。这也意味着它对非ASCII字符的处理更激进,字符集设置不当时反而容易出现乱码。

函数签名:

htmlentities(string $string, int $flags = ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, ?string $encoding = null, bool $double_encode = true): string

四个参数中,只有$string是必填,其余可选。

二、参数逐项拆解

string(必填)

待转换的原始字符串。它就是你要输出到HTML页面上的内容,通常来自用户输入、数据库读取或接口返回。

flags(可选)

控制引号处理方式以及无效编码的处理策略。常见的引号相关常量:

  • ENT_COMPAT:只转换双引号,保留单引号。

  • ENT_QUOTES:同时转换双引号和单引号。

  • ENT_NOQUOTES:不转换任何引号。

编码处理相关常量:

  • ENT_IGNORE:遇到无效编码序列时静默丢弃,不推荐,容易丢数据。

  • ENT_SUBSTITUTE:用U+FFFD替换无效序列,比ENT_IGNORE更安全。

  • ENT_HTML401、ENT_HTML5、ENT_XHTML、ENT_XML1:指定文档类型,影响实体名称的生成方式。

character-set(可选)

指定字符集,如UTF-8、ISO-8859-1、GB2312。省略时使用PHP配置中的默认字符集。这个参数对中文项目尤其关键。

double_encode(可选)

布尔值,默认true。表示是否对已有的HTML实体再次编码。如果设为false,已经存在的&amp;不会被二次转成&amp;amp;。

三、代码号学习编程示例

先看一个基础转换示例,把一段包含HTML标签的字符串输出:

<?php
$str = '<a href="https://www.ebingou.cn">编程学习</a>';
echo htmlentities($str);
?>

输出:

&lt;a href=&quot;https://www.ebingou.cn&quot;&gt;编程学习&lt;/a&gt;

浏览器渲染时,用户看到的是原始标签文本,而不是一个可点击链接。这正是输出转义的意义。

再看引号处理差异:

<?php
$str = "Hello PHP : 'E=MC2'";
echo htmlentities($str, ENT_COMPAT);
echo "<br>";
echo htmlentities($str, ENT_QUOTES);
echo "<br>";
echo htmlentities($str, ENT_NOQUOTES);
?>

输出:

Hello PHP : 'E=MC2'
Hello PHP : &#039;E=MC2&#039;
Hello PHP : 'E=MC2'

ENT_COMPAT只处理双引号,单引号原样保留;ENT_QUOTES把单引号也转成&#039;;ENT_NOQUOTES两者都不动。

中文场景需要显式指定字符集:

<?php
$str = "编程学习 & 代码号";
echo htmlentities($str, ENT_QUOTES, "UTF-8");
?>

输出:

编程学习 &amp; 代码号

如果不指定UTF-8,某些环境下中文可能被错误处理成实体乱码。

四、double_encode的实际影响

假设数据库里已经存了转义后的内容&lt;b&gt;加粗&lt;/b&gt;,再次输出时:

<?php
$stored = "&lt;b&gt;加粗&lt;/b&gt;";

echo htmlentities($stored, ENT_QUOTES, "UTF-8", true);
echo "<br>";
echo htmlentities($stored, ENT_QUOTES, "UTF-8", false);
?>

输出:

&amp;lt;b&amp;gt;加粗&amp;lt;/b&amp;gt;
&lt;b&gt;加粗&lt;/b&gt;

double_encode=true会把&再次转义,页面显示成&lt;b&gt;字面量。double_encode=false则保留原有实体,浏览器渲染成加粗效果。这个参数在处理富文本或已转义数据时很实用。

五、项目反思与踩坑经历

踩坑一:用htmlentities()处理中文导致乱码

早年在做一个留言板时,直接htmlentities($content)输出中文,页面出现大量类似&#20013;的实体。原因是默认字符集不是UTF-8,函数按ISO-8859-1逐字节解析中文,结果全被拆成单字节实体。后来统一写成htmlentities($content,ENT_QUOTES,'UTF-8')才恢复正常。中文项目务必显式传字符集。

踩坑二:把htmlentities()当成SQL注入防护

有同事认为输出转义能防SQL注入,于是在入库前用htmlentities()处理,结果数据库里存了一堆实体,查询和展示都混乱。输出转义只解决HTML上下文的安全问题,SQL注入要用预处理语句。两者职责不同,不能互相替代。

踩坑三:XSS防护选错函数

项目里原本用htmlentities()做用户昵称输出。后来发现昵称中的中文、emoji被过度转换,前端展示偶尔异常。改用htmlspecialchars($str,ENT_QUOTES,'UTF-8')后问题消失。原因是htmlspecialchars()只转义<>&"'这五个字符,足够防XSS,又不会动其他字符。多数输出场景它更合适。

个人建议

  • 普通HTML输出防XSS,优先用htmlspecialchars(),htmlentities()更适合需要把所有字符都转成实体的特殊场景。

  • 无论用哪个,字符集参数都显式写UTF-8。

  • 不要对同一份数据反复转义。入库存原始数据,输出时再转义,这是清晰的分层。

  • 富文本编辑器提交的内容,不要直接htmlentities(),否则标签全变文本。应该用白名单过滤HTML标签。

六、本节课程知识要点

  • htmlentities()把字符串中所有可映射的字符转为HTML实体。

  • 四个参数:字符串、flags、字符集、是否重复编码,仅第一个必填。

  • ENT_COMPAT转双引号,ENT_QUOTES转双引号和单引号,ENT_NOQUOTES都不转。

  • 中文项目必须显式指定UTF-8,否则易乱码。

  • double_encode=false可避免对已有实体二次转义。

  • 防XSS输出转义通常用htmlspecialchars()更合适,htmlentities()范围更广但副作用也更大。

  • 输出转义不能替代SQL预处理。

七、扩展应用场景

场景一:展示用户提交的代码片段

论坛里用户贴出<div>标签,希望原样显示而非被浏览器解析。输出时用htmlentities()转义,页面就呈现源码文本。

场景二:邮件模板中的特殊字符

生成HTML邮件时,商品名里带&或引号,用htmlentities($name,ENT_QUOTES,'UTF-8')可避免邮件客户端解析异常。

场景三:XML数据生成

构造XML节点值时,用htmlentities($value,ENT_QUOTES|ENT_XML1,'UTF-8')能按XML规则转义,比手写替换更稳妥。

htmlentities()的价值在于把字符完整地转成HTML实体,适用范围比htmlspecialchars()更宽。但宽不代表通用,中文乱码、过度转义、误当SQL防护都是常见问题。理解flags和字符集两个参数,分清输出转义与入库处理的边界,才能在项目里用得稳。多数防XSS场景,htmlspecialchars()已经够用;确实需要全字符实体化时,再考虑htmlentities(),并且记得把字符集写清楚。

← PHP hex2bin()十六进制转ASCII字符函数详解 PHP html_entity_decode()函数:HTML实体还原字符教程 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号