html_entity_decode

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

html_entity_decode将 HTML 实体转换为相应的字符

描述

html_entity_decode(string $string, int $flags = ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, ?string $encoding = null): string

html_entity_decode()htmlentities() 相反,它将 string 中的 HTML 实体转换为相应的字符。

更准确地说,此函数解码所有实体(包括所有数字实体),这些实体 a) 对所选文档类型来说一定是有效的——例如,对于 XML,此函数不解码可能在某些 DTD 中定义的命名实体——以及 b) 其字符或字符在与所选编码关联的编码字符集中,并且在所选文档类型中允许。所有其他实体保持原样。

参数

string

输入字符串。

flags

一个或多个以下标志的位掩码,指定如何处理引号以及使用哪个文档类型。默认值为 ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401

可用的 flags 常量
常量名称 描述
ENT_COMPAT 将转换双引号,而单引号保持不变。
ENT_QUOTES 将转换双引号和单引号。
ENT_NOQUOTES 双引号和单引号均不转换。
ENT_SUBSTITUTE 用 Unicode 替换字符 U+FFFD (UTF-8) 或 � (其他) 替换无效的代码单元序列,而不是返回空字符串。
ENT_HTML401 将代码视为 HTML 4.01 处理。
ENT_XML1 将代码视为 XML 1 处理。
ENT_XHTML 将代码视为 XHTML 处理。
ENT_HTML5 将代码视为 HTML 5 处理。

encoding

一个可选参数,定义转换字符时使用的编码。

如果省略,encoding 默认值为 default_charset 配置选项的值。

虽然此参数在技术上是可选的,但强烈建议您为您的代码指定正确的值,如果 default_charset 配置选项可能为给定输入设置不正确。

支持以下字符集

支持的字符集
字符集 别名 描述
ISO-8859-1 ISO8859-1 西欧,Latin-1。
ISO-8859-5 ISO8859-5 很少使用的西里尔字符集(Latin/Cyrillic)。
ISO-8859-15 ISO8859-15 西欧,Latin-9。添加了欧元符号、Latin-1 (ISO-8859-1) 中缺少的法语和芬兰语字母。
UTF-8   与 ASCII 兼容的多字节 8 位 Unicode。
cp866 ibm866, 866 DOS 特定的西里尔字符集。
cp1251 Windows-1251, win-1251, 1251 Windows 特定的西里尔字符集。
cp1252 Windows-1252, 1252 Windows 特定的西欧字符集。
KOI8-R koi8-ru, koi8r 俄语。
BIG5 950 繁体中文,主要用于台湾。
GB2312 936 简体中文,国家标准字符集。
BIG5-HKSCS   带有香港扩展的 Big5,繁体中文。
Shift_JIS SJIS, SJIS-win, cp932, 932 日语
EUC-JP EUCJP, eucJP-win 日语
MacRoman   Mac OS 使用的字符集。
''   空字符串会激活从脚本编码(Zend 多字节)、default_charset 和当前区域设置(参见 nl_langinfo()setlocale())进行检测,按此顺序进行。不推荐。

注意: 其他任何字符集都不会被识别。将使用默认编码,并发出警告。

返回值

返回解码后的字符串。

变更日志

版本 描述
8.1.0 flagsENT_COMPAT 更改为 ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401
8.0.0 encoding 现在可以为空。

示例

示例 #1 解码 HTML 实体

<?php
$orig
= "I'll \"walk\" the <b>dog</b> now";

$a = htmlentities($orig);

$b = html_entity_decode($a);

echo
$a; // I'll &quot;walk&quot; the &lt;b&gt;dog&lt;/b&gt; now

echo $b; // I'll "walk" the <b>dog</b> now
?>

注释

注意:

您可能想知道为什么 trim(html_entity_decode('&nbsp;')); 不能将字符串缩减为空字符串,那是因为 '&nbsp;' 实体不是 ASCII 代码 32(被 trim() 剥离),而是在默认 ISO 8859-1 编码中的 ASCII 代码 160 (0xa0)。

参见

添加注释

用户贡献注释 20 个注释

Martin
13 年前
如果您需要一些将 &#[0-9]+ 实体转换为 UTF-8 的东西,这很简单,而且有效

<?php
/* 实体乱码。 /
$input = "Fovi&#269;";

$output = preg_replace_callback("/(&#[0-9]+;)/", function($m) { return mb_convert_encoding($m[1], "UTF-8", "HTML-ENTITIES"); }, $input);

/* 纯 UTF-8。 */
echo $output;
?>
txnull
8 年前
使用以下方法解码所有实体
<?php html_entity_decode($string, ENT_QUOTES | ENT_XML1, 'UTF-8') ?>

我检查了这些特殊实体
- 双引号 (&#34;)
- 单引号 (&#39; 和 &apos;)
- 不可打印字符(例如 &#13;)
使用其他 $flags,某些或所有字符将不会被解码。

似乎 ENT_XML1 和 ENT_XHTML 在解码时是相同的。
aidan at php dot net
19 年前
此功能现在在 PEAR 包 PHP_Compat 中实现。

有关在不升级 PHP 版本的情况下使用此函数的更多信息,请访问以下链接

http://pear.php.net/package/PHP_Compat
Benjamin
11 年前
以下函数解码命名和数字 HTML 实体,并在 UTF-8 上工作。需要 iconv。

function decodeHtmlEnt($str) {
$ret = html_entity_decode($str, ENT_COMPAT, 'UTF-8');
$p2 = -1;
for(;;) {
$p = strpos($ret, '&#', $p2+1);
if ($p === FALSE)
break;
$p2 = strpos($ret, ';', $p);
if ($p2 === FALSE)
break;

if (substr($ret, $p+2, 1) == 'x')
$char = hexdec(substr($ret, $p+3, $p2-$p-3));
else
$char = intval(substr($ret, $p+2, $p2-$p-2));

//echo "$char\n";
$newchar = iconv(
'UCS-4', 'UTF-8',
chr(($char>>24)&0xFF).chr(($char>>16)&0xFF).chr(($char>>8)&0xFF).chr($char&0xFF)
);
//echo "$newchar<$p<$p2<<\n";
$ret = substr_replace($ret, $newchar, $p, 1+$p2-$p);
$p2 = $p + strlen($newchar);
}
return $ret;
}
Daniel A.
6 年前
今天我想使用这个函数,但我发现文档,尤其是关于标志的文档,并不十分有用。

例如,运行下面的代码失败了,因为我使用的标志是错误的……

$string = 'Donna&#039;s Bakery';
$title = html_entity_decode($string, ENT_HTML401, 'UTF-8');
echo $title;

在这种情况下,要使用的正确标志是 ENT_QUOTES。

我理解要使用的标志是与预期的转换结果相对应的标志。因此,对于转换为单引号或双引号的字符,使用 ENT_QUOTES……等等。

请帮助使文档更清晰一些。
php dot net at c dash ovidiu dot tk
19 年前
快速且不干净的代码,将数字实体转换为 UTF-8。

<?php

function replace_num_entity($ord)
{
$ord = $ord[1];
if (
preg_match('/^x([0-9a-f]+)$/i', $ord, $match))
{
$ord = hexdec($match[1]);
}
else
{
$ord = intval($ord);
}

$no_bytes = 0;
$byte = array();

if (
$ord < 128)
{
return
chr($ord);
}
elseif (
$ord < 2048)
{
$no_bytes = 2;
}
elseif (
$ord < 65536)
{
$no_bytes = 3;
}
elseif (
$ord < 1114112)
{
$no_bytes = 4;
}
else
{
return;
}

switch(
$no_bytes)
{
case
2:
{
$prefix = array(31, 192);
break;
}
case
3:
{
$prefix = array(15, 224);
break;
}
case
4:
{
$prefix = array(7, 240);
}
}

for (
$i = 0; $i < $no_bytes; $i++)
{
$byte[$no_bytes - $i - 1] = (($ord & (63 * pow(2, 6 * $i))) / pow(2, 6 * $i)) & 63 | 128;
}

$byte[0] = ($byte[0] & $prefix[0]) | $prefix[1];

$ret = '';
for (
$i = 0; $i < $no_bytes; $i++)
{
$ret .= chr($byte[$i]);
}

return
$ret;
}

$test = 'This is a &#269;&#x5d0; test&#39;';

echo
$test . "<br />\n";
echo
preg_replace_callback('/&#([0-9a-fx]+);/mi', 'replace_num_entity', $test);

?>
Matt Robinson
14 年前
我在之前的评论中写到,html_entity_decode() 只处理了大约 100 个字符。这并不完全正确;它只处理输出字符集(第三个参数)中存在的实体。如果你想获取所有 HTML 实体,确保你使用 ENT_QUOTES 并将第三个参数设置为 'UTF-8'。

如果你不想要一个 UTF-8 字符串,你需要使用 utf8_decode()、iconv() 或 mb_convert_encoding() 等方法在之后进行转换。

如果你正在生成 XML,它不识别大多数 HTML 实体

当生成 UTF-8 文档(默认值)时,那么 htmlspecialchars(html_entity_decode($string, ENT_QUOTES, 'UTF-8'), ENT_NOQUOTES, 'UTF-8')(因为你只需要转义 < 和 > 以及 &,除非你在 XML 标签本身中打印)。

否则,要么将所有命名实体转换为数字实体,要么在文档的 DTD 中声明命名实体。完整的 252 个实体列表可以在 HTML 4.01 规范中找到,或者你可以从我的网站复制粘贴函数 (http://inanimatt.com/php-convert-entities.php)。
Free at Key dot no
14 年前
这是一个便捷的函数,将剩余的 HTML 实体转换为人类可读字符(对于目标字符集中不存在的实体)。

<?php
function cleanString($in,$offset=null)
{
$out = trim($in);
if (!empty(
$out))
{
$entity_start = strpos($out,'&',$offset);
if (
$entity_start === false)
{
// ideal
return $out;
}
else
{
$entity_end = strpos($out,';',$entity_start);
if (
$entity_end === false)
{
return
$out;
}
// zu lang um eine entity zu sein
else if ($entity_end > $entity_start+7)
{
// und weiter gehts
$out = cleanString($out,$entity_start+1);
}
// gottcha!
else
{
$clean = substr($out,0,$entity_start);
$subst = substr($out,$entity_start+1,1);
// &scaron; => "s" / &#353; => "_"
$clean .= ($subst != "#") ? $subst : "_";
$clean .= substr($out,$entity_end+1);
// und weiter gehts
$out = cleanString($clean,$entity_start+1);
}
}
}
return
$out;
}
?>
neurotic dot neu at gmail dot com
14 年前
这是一个安全的 rawurldecode,带有 utf8 检测。

<?php
function utf8_rawurldecode($raw_url_encoded){
$enc = rawurldecode($raw_url_encoded);
if(
utf8_encode(utf8_decode($enc))==$enc){;
return
rawurldecode($raw_url_encoded);
}else{
return
utf8_encode(rawurldecode($raw_url_encoded));
}
}
?>
Victor
12 年前
我们在处理诸如 e-acute 之类的外国字符方面遇到了非常奇怪的行为。

然而,只有在从我们的 mysql 数据库中提取这些字符并通过我们处理 DNS 问题的代理服务器显示时,才会出现问题。

正如其他用户所指出的,当他们将自己的字符设置留空时,默认字符设置并非他们所期望的。

当我们将默认字符集更改为“UTF-8”时,在处理诸如e-acute之类的外来字符时,不再需要使用这些函数。这对我们来说已经足够了!
匿名
3 年前
为什么 html_entity_decode() 函数不将没有最后分号的实体(如 &#x41 或 &#65)转换为字符?

---
<?php
echo 'like &#x41 or &#65';
---

浏览器显示正常:
----
like A or A
me at richardsnazell dot com
16 年前
我在电子邮件主题行中正确显示“TM”商标符号时遇到了问题。使用带有不同字符集的 html_entity_decode() 无法解决问题,但直接将实体替换为其 ASCII 等效项可以解决问题。

$subject = str_replace('&trade;', chr(153), $subject);
jojo
17 年前
解密由 JavaScript 的转义函数编码的字符。
当在页面上使用多字节时,它很有效。

javascript escape('aaああaa') ..... 'aa%u3042%u3042aa'
php jsEscape_decode('aa%u3042%u3042aa')..'aaああaa'

<?php
function jsEscape_decode($jsEscaped,$outCharCode='SJIS'){
$arrMojis = explode("%u",$jsEscaped);
for (
$i = 1;$i < count($arrMojis);$i++){
$c = substr($arrMojis[$i],0,4);
$cc = mb_convert_encoding(pack('H*',$c),$outCharCode,'UTF-16');
$arrMojis[$i] = substr_replace($arrMojis[$i],$cc,0,4);
}
return
implode('',$arrMojis);
}
?>
florianborn (at) yahoo (dot) de
19 年前
注意

<?php

echo urlencode(html_entity_decode("&nbsp;"));

?>

将输出 "%A0" 而不是 "+"。
daniel at brightbyte dot de
19 年前
此函数似乎有两个限制(至少在 PHP 4.3.8 中)。

a) 它不适用于多字节字符编码,如 UTF-8。
b) 它不解码数字实体引用。

a) 可以通过使用 iconv 转换为 ISO-8859-1,然后解码实体,然后再次转换为 UTF-8 来解决。但这非常丑陋,会破坏 Latin-1 中不存在的所有字符。

b) 可以使用以下代码很好地解决。

<?php
function decode_entities($text) {
$text= html_entity_decode($text,ENT_QUOTES,"ISO-8859-1"); #注意:UTF-8 不起作用!
$text= preg_replace('/&#(\d+);/me',"chr(\\1)",$text); #十进制表示法
$text= preg_replace('/&#x([a-f0-9]+);/mei',"chr(0x\\1)",$text); #十六进制表示法
return $text;
}
?>

希望对你有帮助。
slickriptide at gmail dot com
7 年前
使用此函数时,最好注意它说将字符集参数留空“不推荐”。

我遇到过一个问题,我将带有实体转换的文本文件存储到数据库中。当我稍后检索它们并运行以下代码时

$text_file = html_entity_decode($text_data);

实体没有被解码。

一旦意识到这个问题,我就将解码调用更改为完全指定所有参数。

$text_file = html_entity_decode($text_data, ENT_COMPAT | ENT_HTML5,'utf-8');

这按预期转换了实体。
grvg (at) free (dot) fr
18 年前
以下是将 HTML 实体转换为 UTF-8 的终极函数。
主要函数是 htmlentities2utf8。
其他是辅助函数。

<?php
function chr_utf8($code)
{
if (
$code < 0) return false;
elseif (
$code < 128) return chr($code);
elseif (
$code < 160) // Remove Windows Illegals Cars
{
if (
$code==128) $code=8364;
elseif (
$code==129) $code=160; // not affected
elseif ($code==130) $code=8218;
elseif (
$code==131) $code=402;
elseif (
$code==132) $code=8222;
elseif (
$code==133) $code=8230;
elseif (
$code==134) $code=8224;
elseif (
$code==135) $code=8225;
elseif (
$code==136) $code=710;
elseif (
$code==137) $code=8240;
elseif (
$code==138) $code=352;
elseif (
$code==139) $code=8249;
elseif (
$code==140) $code=338;
elseif (
$code==141) $code=160; // not affected
elseif ($code==142) $code=381;
elseif (
$code==143) $code=160; // not affected
elseif ($code==144) $code=160; // not affected
elseif ($code==145) $code=8216;
elseif (
$code==146) $code=8217;
elseif (
$code==147) $code=8220;
elseif (
$code==148) $code=8221;
elseif (
$code==149) $code=8226;
elseif (
$code==150) $code=8211;
elseif (
$code==151) $code=8212;
elseif (
$code==152) $code=732;
elseif (
$code==153) $code=8482;
elseif (
$code==154) $code=353;
elseif (
$code==155) $code=8250;
elseif (
$code==156) $code=339;
elseif (
$code==157) $code=160; // not affected
elseif ($code==158) $code=382;
elseif (
$code==159) $code=376;
}
if (
$code < 2048) return chr(192 | ($code >> 6)) . chr(128 | ($code & 63));
elseif (
$code < 65536) return chr(224 | ($code >> 12)) . chr(128 | (($code >> 6) & 63)) . chr(128 | ($code & 63));
else return
chr(240 | ($code >> 18)) . chr(128 | (($code >> 12) & 63)) . chr(128 | (($code >> 6) & 63)) . chr(128 | ($code & 63));
}

// Callback for preg_replace_callback('~&(#(x?))?([^;]+);~', 'html_entity_replace', $str);
function html_entity_replace($matches)
{
if (
$matches[2])
{
return
chr_utf8(hexdec($matches[3]));
} elseif (
$matches[1])
{
return
chr_utf8($matches[3]);
}
switch (
$matches[3])
{
case
"nbsp": return chr_utf8(160);
case
"iexcl": return chr_utf8(161);
case
"cent": return chr_utf8(162);
case
"pound": return chr_utf8(163);
case
"curren": return chr_utf8(164);
case
"yen": return chr_utf8(165);
//... etc with all named HTML entities
}
return
false;
}

function
htmlentities2utf8 ($string) // because of the html_entity_decode() bug with UTF-8
{
$string = preg_replace_callback('~&(#(x?))?([^;]+);~', 'html_entity_replace', $string);
return
$string;
}
?>
marion at figmentthinking dot com
15 年前
我刚刚遇到了
Bug #27626 html_entity_decode 错误 - html_entity_decode() 无法处理 MBCS!

如果您仍在运行 PHP 4,则简单的解决方案是使用 utf8_decode() 函数包装 html_entity_decode() 函数。

<?php
$string
= '&nbsp;';
$utf8_encode = utf8_encode(html_entity_decode($string));
?>

默认情况下,html_entity_decode() 返回 ISO-8859-1 字符集,而 utf8_decode() 默认情况下...

http://us.php.net/manual/en/function.utf8-decode.php
"将使用 UTF-8 编码的 ISO-8859-1 字符串转换为单字节 ISO-8859-1"
kae at verens dot com
16 年前
示例中 unhtmlentities() 函数中的 'chr()' 引用应更改为 unichr,使用 'chr' 引用 (https://php.net/chr) 中描述的 unichr() 函数。

这样做的原因是像 &#x20AC; 这样的字符不能分解为 ASCII 数字(顺便说一下,这是欧元符号)。
jl dot garcia at gmail dot com
15 年前
我创建了这个函数来过滤所有进出数据库的文本。

<?php
function filter_string($string, $nohtml='', $save='') {
if(!empty(
$nohtml)) {
$string = trim($string);
if(!empty(
$save)) $string = htmlentities(trim($string), ENT_QUOTES, 'ISO-8859-15');
else
$string = html_entity_decode($string, ENT_QUOTES, 'ISO-8859-15');
}
if(!empty(
$save)) $string = mysql_real_escape_string($string);
else
$string = stripslashes($string);
return(
$string);
}
?>
To Top