2024年PHP开发者大会日本站

htmlentities

(PHP 4, PHP 5, PHP 7, PHP 8)

htmlentities将所有适用字符转换为HTML实体

描述

htmlentities(
    字符串 $string,
    整数 $flags = ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401,
    ?字符串 $encoding = null,
    布尔值 $double_encode = true
): 字符串

此函数与htmlspecialchars()完全相同,区别在于使用htmlentities()时,所有具有HTML字符实体等效项的字符都将转换为这些实体。get_html_translation_table() 函数可用于返回根据提供的 flags 常量使用的转换表。

如果要进行解码(反向操作),可以使用html_entity_decode()

参数

字符串

输入字符串。

flags

一个或多个以下标志的位掩码,用于指定如何处理引号、无效代码单元序列和使用的文档类型。默认值为 ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401

可用的 flags 常量
常量名称 描述
ENT_COMPAT 将转换双引号,而保留单引号。
ENT_QUOTES 将转换双引号和单引号。
ENT_NOQUOTES 将保留双引号和单引号。
ENT_IGNORE 静默丢弃无效的代码单元序列,而不是返回空字符串。不建议使用此标志,因为它» 可能存在安全隐患
ENT_SUBSTITUTE 用 Unicode 替换字符 U+FFFD (UTF-8) 或 &#FFFD; (其他) 替换无效的代码单元序列,而不是返回空字符串。
ENT_DISALLOWED 将给定文档类型中无效的代码点替换为 Unicode 替换字符 U+FFFD (UTF-8) 或 &#FFFD; (其他),而不是保留它们。例如,这对于确保包含嵌入式外部内容的 XML 文档的格式良好可能很有用。
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())的顺序进行检测。不推荐。

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

double_encode

double_encode关闭时,PHP将不会编码现有的HTML实体。默认情况下会转换所有内容。

返回值

返回编码后的字符串。

如果输入string在给定的encoding中包含无效的代码单元序列,则将返回空字符串,除非设置了ENT_IGNOREENT_SUBSTITUTE标志。

变更日志

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

范例

示例 #1 一个 htmlentities() 示例

<?php
$str
= "A 'quote' is <b>bold</b>";

echo
htmlentities($str);
echo
"\n\n";
echo
htmlentities($str, ENT_COMPAT);
?>

以上示例将输出

A &#039;quote&#039; is &lt;b&gt;bold&lt;/b&gt;

A 'quote' is &lt;b&gt;bold&lt;/b&gt

示例 #2 ENT_IGNORE 的用法

<?php
$str
= "\x8F!!!";

// 输出空字符串
echo htmlentities($str, ENT_QUOTES, "UTF-8");

// 输出 "!!!"
echo htmlentities($str, ENT_QUOTES | ENT_IGNORE, "UTF-8");
?>

参见

添加注释

用户贡献的注释 22条注释

Sijmen Ruwhof
14年前
下面是一个重要说明,关于如何使用此函数来保护您的应用程序免受跨站脚本 (XSS) 漏洞的攻击。

当在 HTML 标签的属性中打印用户输入时,如果使用单引号定义标签属性值的边界,则 `htmlEntities()` 的默认配置无法防止 XSS 攻击。这时可以通过注入单引号来实现 XSS 攻击。

<?php
$_GET
['a'] = "#000' onload='alert(document.cookie)";
?>

可能发生 XSS 攻击(不安全)

<?php
$href
= htmlEntities($_GET['a']);
print
"<body bgcolor='$href'>"; # 结果为:<body bgcolor='#000' onload='alert(document.cookie)'>
?>

使用 'ENT_QUOTES' 引用样式选项,确保不会发生 XSS 攻击,并且您的应用程序是安全的

<?php
$href
= htmlEntities($_GET['a'], ENT_QUOTES);
print
"<body bgcolor='$href'>"; # 结果为:<body bgcolor='#000&#039; onload=&#039;alert(document.cookie)'>
?>

'ENT_QUOTES' 选项无法防止在某些标签属性(例如 'a' 标签的 'href' 属性)中执行 JavaScript 代码。单击下面的链接时,将执行给定的 JavaScript 代码。

<?php
$_GET
['a'] = 'javascript:alert(document.cookie)';
$href = htmlEntities($_GET['a'], ENT_QUOTES);
print
"<a href='$href'>link</a>"; # 结果为:<a href='javascript:alert(document.cookie)'>link</a>
?>
[email protected]
2 年前
以上答案对于法语等多种语言不正确
我已经纠正了它
函数 xml_entities($strIn)
{
如果 (is_numeric($strIn)) {
返回 $strIn;
}
$strOut = null;

$arrStr = mb_str_split($strIn);
foreach ($arrStr as $char) {
$ord = mb_ord($char);

如果 (($ord > 0 && $ord < 32) || ($ord >= 127)) {
$strOut .= "&amp;#{$ord};";
}
否则 {
switch ($char) {
case '<'
$strOut .= '&lt;';
break;
case '>'
$strOut .= '&gt;';
break;
case '&'
$strOut .= '&amp;';
break;
case '"'
$strOut .= '&quot;';
break;
default
$strOut .= $char;
}
}
}

返回 $strOut;
}
[email protected]
17 年前
我见过很多将所有实体转换的函数,但我需要在一个数据库字段中进行全文搜索,该字段包含命名实体而不是数字实体(由 tinymce 编辑),所以我搜索了 tinymce 源代码并找到一个包含值->实体映射的字符串。因此,我编写了以下函数来使用命名实体对用户的查询进行编码。

我使用的字符串与原始字符串不同,因为我不想转换 ' 或 "。字符串太长,我不得不将其剪切。要获取原始字符串,请检查 TinyMCE 源代码并搜索 nbsp 或其他实体;)

<?php

$entities_unmatched
= explode(',', '160,nbsp,161,iexcl,162,cent, [...] ');
$even = 1;
foreach(
$entities_unmatched as $c) {
if(
$even) {
$ord = $c;
} else {
$entities_table[$ord] = $c;
}
$even = 1 - $even;
}

function
encode_named_entities($str) {
global
$entities_table;

$encoded_str = '';
for(
$i = 0; $i < strlen($str); $i++) {
$ent = @$entities_table[ord($str{$i})];
if(
$ent) {
$encoded_str .= "&$ent;";
} else {
$encoded_str .= $str{$i};
}
}
return
$encoded_str;
}

?>
[email protected]
6 年前
<?php

/**
* 将中文转为Html实体
* Convert Chinese in HTML to entity
* 作者 QiangGe
* 邮箱 [email protected]
*
*/

$str = <<<EOT
你好 world
EOT;

function
ChineseToEntity($str) {
return
preg_replace_callback(
'/[\x{4e00}-\x{9fa5}]/u', // utf-8
// '/[\x7f-\xff]+/', // 如果是 gb2312
function ($matches) {
$json = json_encode(array($matches[0]));
preg_match('/\[\"(.*)\"\]/', $json, $arr);
/*
* 通过json_encode函数将中文转为unicode
* 然后用正则取出unicode
* Turn the Chinese into Unicode through the json_encode function, then extract Unicode from regular.
* 我认为这个主意很巧妙。
*/
return '&#x'. str_replace('\\u', '', $arr[1]). ';';
},
$str
);
}

echo
ChineseToEntity($str);
// &#x4f60;&#x597d; world
[email protected]
14年前
以下方法可以使字符串完全安全地用于 XML

<?php
function philsXMLClean($strin) {
$strout = null;

for (
$i = 0; $i < strlen($strin); $i++) {
$ord = ord($strin[$i]);

if ((
$ord > 0 && $ord < 32) || ($ord >= 127)) {
$strout .= "&amp;#{$ord};";
}
else {
switch (
$strin[$i]) {
case
'<':
$strout .= '&lt;';
break;
case
'>':
$strout .= '&gt;';
break;
case
'&':
$strout .= '&amp;';
break;
case
'"':
$strout .= '&quot;';
break;
default:
$strout .= $strin[$i];
}
}
}

return
$strout;
}
?>
hajo-p
10 年前
标志 ENT_HTML5 还会使用 htmlentities 去除换行符(如 \n),而 htmlspecialchars 则不受影响。

如果您之后想对该字符串使用 nl2br,您最终可能会像我一样搜索问题。这并不适用于其他标志,例如 ENT_XHTML,这让我感到困惑。

我已经使用 PHP 5.4/5.5/5.6-dev 测试了这一点,结果相同,所以这似乎是一个预期的“特性”。
[email protected]
18 年前
如果您正在为 Flash 创建 loadvars 页面,并且遇到特殊字符(例如 " & "、" ' " 等)的问题,则应为 Flash 对其进行转义。

尝试在 Flash 的 ActionScript 中使用 trace(escape("&")); 来查看 & 的转义代码。

% = %25
& = %26
' = %27

<?php
function flashentities($string){
return
str_replace(array("&","'"),array("%26","%27"),$string);
}
?>

这两个函数让我比较担心。你的情况可能会有所不同(YMMV)。
[email protected]
12年前
对于那些西班牙语(以及其他语言)使用者来说,在使用htmlentities()后想找回他们的特殊字符 :)

<?php
protected function _decodeAccented($encodedValue, $options = array()) {
$options += array(
'quote' => ENT_NOQUOTES,
'encoding' => 'UTF-8',
);
return
preg_replace_callback(
'/&\w(acute|uml|tilde);/',
create_function(
'$m',
'return html_entity_decode($m[0], ' . $options['quote'] . ', "' .
$options['encoding'] . '");'
),
$encodedValue
);
}
?>
[email protected]
12年前
你好:

经过多次测试,我发现:

- 当你指定标志和字符集时,htmlentities() 函数会移除诸如 "à"、"è" 等字符。

- 当你什么都不指定时,htmlentities() 函数不会移除上述字符。

所以,让我们假设:

<?php

$str
= "Hèèèllooo";

$res_1 = htmlentities($str, ENT_QUOTES, "UTF-8");
$res_2 = htmlentities($str);

echo
var_dump($res_1); // 结果:string '' (length=0)
echo var_dump($res_2); // string 'H&egrave;&egrave;&egrave;llooo' (length=30)

?>

我将此用于文本区域的评论内容。无论如何,请注意,使用 “$res_2” 形式的函数会保留未转换的单引号/双引号。此时,你应该使用 str_replace() 函数来处理这些字符,但要小心,因为:

<?php

$str
= "'Hèèèllooo'";

$res_2 = str_replace("'","&#039;",$str);
$res_2 = htmlentities($str);
echo
var_dump($res_2); // string '&amp;#039;H&egrave;&egrave;&egrave;llooo&amp;#039;'

$res_3 = htmlentities($str);
$res_3 = str_replace("'","&#039;",$res_3);
echo
var_dump($res_3); // string '&#039;H&egrave;&egrave;&egrave;llooo&#039;' --> 正确
?>

希望这能帮到你。

此致敬礼,
W.D.
[email protected]
12年前
htmlentities() 函数不会编码所有 Unicode 字符。它只编码它能编码的字符(所有 Latin-1 字符),其他的字符则会保留。&#1033; 就是我用到的一个棘手的例子。我搜索过能编码所有字符的函数,但最终还是自己写了一个。这就是我能做到的最简单的版本了。可以参考 ANSI 表格来自定义包含/排除你想要/不想要的字符。我确定它速度不是很快。

// 支持Unicode的htmlentities函数。
// 将“正常”字符作为字符返回,并将特殊字符作为数字 HTML 实体返回。
function superentities( $str ){
// 去除已存在的实体,否则会双重转义
$str = html_entity_decode(stripslashes($str),ENT_QUOTES,'UTF-8');
$ar = preg_split('/(?<!^)(?!$)/u', $str ); // 返回每个多字节字符的数组
foreach ($ar as $c){
$o = ord($c);
if ( (strlen($c) > 1) || /* 多字节 [unicode] */
($o <32 || $o > 126) || /* <- 控制字符 / latin 特殊字符 -> */
($o >33 && $o < 40) ||/* 引号 + 和号 */
($o >59 && $o < 63) /* html */
) {
// 转换为数字实体
$c = mb_encode_numericentity($c,array (0x0, 0xffff, 0, 0xffff), 'UTF-8');
}
$str2 .= $c;
}
return $str2;
}
Bassie (:
21年前
请注意,在使用任何其他编辑文本的函数(如 nl2br())之前,你应该使用 htmlentities()。

如果你先使用 nl2br(),htmlentities() 函数会将 <br> 更改为 &lt;br&gt;。
[email protected]
13年前
htmlentities 函数在 5.1.6 和 5.3.3 版本之间似乎发生了一些变化,现在它对于包含英镑符号的任何内容都返回空字符串。

$ php -v
PHP 5.1.6 (cli) (built: May 22 2008 09:08:44)
$ php -r "echo htmlentities('£hello', null, 'utf-8');"
&pound;hello
$

$ php -v
PHP 5.3.3 (cli) (built: Aug 19 2010 12:07:49)
$ php -r "echo htmlentities('£hello', null, 'utf-8');"
$

(第二次返回空字符串)

只是一个提示。
Waygood
13年前
当在注释标签 <!-- --> 中放置值时,你应该将 -- 替换为 &#45;&#45;,因为这将结束你的标签并显示注释的其余部分。
[email protected]
13年前
一个有用的函数,用于转换不同输入中的符号。
<?php
function ConvertSimbols($var, $ConvertQuotes = 0) {
if (
$ConvertQuotes > 0) {
$var = htmlentities($var, ENT_NOQUOTES, 'UTF-8');
$var = str_replace('\"', '', $var);
$var = str_replace("\'", '', $var);
} else {
$var = htmlentities($var, ENT_QUOTES, 'UTF-8');
}
return
$var;
}
?>

例如消息的带引号用法

$message = ConvertSimbols($message);

例如链接的无引号用法

$link = ConvertSimbols($link, 1);
Jeff
6 年前
使用 AJAX 调用 PHP 向 XML 写入数据时,有一个很少被提及的功能。我花了几个小时使用 htmlentities(),因为写入我的 XML 文档的内容与预期不符。我自然地认为,在将字符串写入 XML 之前,我应该转换它们以符合 XML 关于非法字符的规则。令我惊讶的是,当使用 htmlentities() 或 htmlspecialchars() 转换后,再写入 XML 文件时,生成的和号会被再次转换!请考虑以下示例

<?php
$str
= "<b>I am cool</b>" ;
$str = htmlentities($str) ;
?>

当你将 $str 附加到 XML 元素并保存() 文档时,你期望 XML 文档的源代码看起来像这样

<ele>&lt;b&gt;I am cool&lt;/b&gt;</ele>

但事实并非如此。生成的和号会被 PHP 自动转换为 &amp;,你的源代码最终看起来像这样

<ele>&amp;lt;b&amp;gt;I am cool&amp;lt;/b&amp;gt;</ele>

如你所见,这在尝试将 XML 数据输出回 HTML 时会产生问题。重要的是要记住,当以这种方式写入 XML 时,PHP 会自动转换特殊字符,例如 “>” 和 “<”,在某些情况下就不需要使用 htmlentities() 了。我假设此功能是为了辅助通过 header 查询传递数据,以避免保留字符与 header 查询中的其他字符冲突(例如 & 或 =)。现在我理解旧版本的 PHP 可能并非如此,这可能是我的 PHP 版本(PHP 版本 5.6.32)的一个特性。对于旧版本,我假设必须使用 htmlentities() 或 htmlspecialchars(),正如这里之前的注释中所述。此外,我在我的 HTML 和 XML 中使用 UTF-8 字符集,我不确定这是否也会影响我的结果。

总之,我花了几个小时尝试使用htmlentities()函数转换字符串以便写入和保存XML,而实际上我只需要不做任何转换,让PHP自行处理字符串就可以了。我希望这能帮到大家,因为我认为我并非唯一一个遇到这个问题的人。
Tom Walter
16年前
请注意,从5.2.5版本开始,如果输入字符串包含无效的字符(对于您指定的输出编码无效),则此函数将返回null。

您可能期望它只去除无效字符,但它不会。

您可以自己去除这些字符,如下所示:

iconv('utf-8','utf-8',$str);

您也可以将它与htmlentities结合使用:

$str = htmlentities(iconv('UTF-8', 'UTF-8//IGNORE', $str, ENT_QUOTES, 'UTF-8');

这应该会给您一个使用htmlentities编码为utf-8的字符串,并且任何不支持的字符都被去除。
jake_mcmahon at hotmail dot com
20年前
此函数对于防止XSS(跨站脚本攻击)特别有用。XSS利用代码中的漏洞,无论是Javascript还是PHP。XSS通常(如果不是总是)使用HTML实体来进行恶意操作,因此此函数与您的脚本(特别是搜索或提交脚本)配合使用,是打击“黑客”的非常有用的工具。
steve at mcdragonsoftware dot com
13年前
我很高兴5.4版本支持xml,但是我们许多人仍在使用旧版本,有些人仍在使用PHP4。如果您像我一样,您可能会对尝试将htmlentites/htmlspecialchars与xml输出一起使用感到沮丧。我希望找到一个强制使用数字编码的选项,缺少这个选项,我编写了自己的xmlencode函数,现在我提供给大家。

用法

$string xmlencode( $string )

它将对有效的xml实体amp、quote、lt、gt、(apos)使用htmlspecialchars,并对所有其他非字母数字字符返回数字实体。

-------------------------------------------

<?php
if( !function_exists( 'xmlentities' ) ) {
function
xmlentities( $string ) {
$not_in_list = "A-Z0-9a-z\s_-";
return
preg_replace_callback( "/[^{$not_in_list}]/" , 'get_xml_entity_at_index_0' , $string );
}
function
get_xml_entity_at_index_0( $CHAR ) {
if( !
is_string( $CHAR[0] ) || ( strlen( $CHAR[0] ) > 1 ) ) {
die(
"function: 'get_xml_entity_at_index_0' requires data type: 'char' (single character). '{$CHAR[0]}' does not match this type." );
}
switch(
$CHAR[0] ) {
case
"'": case '"': case '&': case '<': case '>':
return
htmlspecialchars( $CHAR[0], ENT_QUOTES ); break;
default:
return
numeric_entity_4_char($CHAR[0]); break;
}
}
function
numeric_entity_4_char( $char ) {
return
"&#".str_pad(ord($char), 3, '0', STR_PAD_LEFT).";";
}
}
?>
h_guillaume at hotmail dot com
14年前
我使用此函数编码所有xml实体以及所有未在xml中定义的&something;,例如&trade;。
您也可以使用我的解码函数解码已编码的内容。
我的函数的工作方式有点像htmlentities。
如果您想将某些字符串排除在编码之外,也可以将其他字符串添加到数组中。

<?php
function xml_entity_decode($text, $charset = 'Windows-1252'){
// 双重解码,因此如果值为 &amp;trade;,它将变成商标
$text = html_entity_decode($text, ENT_COMPAT, $charset);
$text = html_entity_decode($text, ENT_COMPAT, $charset);
return
$text;
}

function
xml_entities($text, $charset = 'Windows-1252'){
// 调试和测试
// $text = "test &amp; &trade; &amp;trade; abc &reg; &amp;reg; &#45;";

// 首先,我们对在xml中也无效的html字符进行编码
$text = htmlentities($text, ENT_COMPAT, $charset, false);

// 来自维基的XML字符实体数组
// 注意:&apos; 在UTF-8或UTF-16中没用
$arr_xml_special_char = array("&quot;","&amp;","&apos;","&lt;","&gt;");

// 构建正则表达式字符串以排除所有包含xml特殊字符的字符串
$arr_xml_special_char_regex = "(?";
foreach(
$arr_xml_special_char as $key => $value){
$arr_xml_special_char_regex .= "(?!$value)";
}
$arr_xml_special_char_regex .= ")";

// 扫描数组以查找 &something_not_xml; 语法
$pattern = "/$arr_xml_special_char_regex&([a-zA-Z0-9]+;)/";

// 将 &something_not_xml; 替换为 &amp;something_not_xml;
$replacement = '&amp;${1}';
return
preg_replace($pattern, $replacement, $text);
}
?>
za at byza dot it
16年前
使用不同字符集的文件时遇到问题?

htmlentities和html_entity_decode可用于字符集之间的转换!

示例函数

<?php
function utf2latin($text) {
$text=htmlentities($text,ENT_COMPAT,'UTF-8');
return
html_entity_decode($text,ENT_COMPAT,'ISO-8859-1');
}
?>
chris at ocproducts dot com
7年前
即使设置了ENT_SUBSTITUTE,此函数也会对错误输入发出警告,因此请做好准备。
drallen at cs dot uwaterloo dot ca
14年前
如果您打算将字符集中的*所有*字符转换为相应的HTML实体,而不仅仅是命名字符,请参考https://php.net/manual/en/function.mb-convert-encoding.php。未命名的字符将被替换为HTML数字编码。例如:

$text = mb_convert_encoding($text, 'HTML-ENTITIES', "UTF-8");
To Top