htmlspecialchars

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

htmlspecialchars将特殊字符转换为 HTML 实体

描述

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

某些字符在 HTML 中具有特殊意义,如果要保留其含义,则应使用 HTML 实体表示它们。此函数返回一个已进行这些转换的字符串。如果您需要将所有具有关联命名实体的输入子字符串进行转换,请改用 htmlentities()

如果传递给此函数的输入字符串和最终文档共享相同的字符集,则此函数足以准备输入以包含在 HTML 文档的大多数上下文中。但是,如果输入可以表示最终文档字符集中未编码的字符,并且您希望保留这些字符(作为数字或命名实体),则此函数和 htmlentities()(仅编码具有命名实体等效项的子字符串)可能都不够。您可能需要改用 mb_encode_numericentity()

执行的转换
字符 替换
& (和号) &
" (双引号) ", 除非设置了 ENT_NOQUOTES
' (单引号) ' (对于 ENT_HTML401) 或 ' (对于 ENT_XML1ENT_XHTMLENT_HTML5),但仅当设置了 ENT_QUOTES
< (小于) &lt;
> (大于) &gt;

参数

string

要转换的 string

flags

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

可用的 flags 常量
常量名称 描述
ENT_COMPAT 将转换双引号,而保留单引号。
ENT_QUOTES 将转换双引号和单引号。
ENT_NOQUOTES 将保留双引号和单引号,不进行转换。
ENT_IGNORE 静默丢弃无效代码单元序列,而不是返回空字符串。使用此标志不建议,因为它 » 可能会存在安全隐患
ENT_SUBSTITUTE 将无效代码单元序列替换为 Unicode 替换字符 U+FFFD (UTF-8) 或 &#xFFFD; (否则),而不是返回空字符串。
ENT_DISALLOWED 将给定文档类型的无效代码点替换为 Unicode 替换字符 U+FFFD (UTF-8) 或 &#xFFFD; (否则),而不是保留原样。例如,这可能有助于确保包含嵌入式外部内容的 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-1ISO-8859-15UTF-8cp866cp1251cp1252KOI8-R 实际上是等效的,前提是 string 本身对编码有效,因为受 htmlspecialchars() 影响的字符在所有这些编码中的位置相同。

支持以下字符集

支持的字符集
字符集 别名 描述
ISO-8859-1 ISO8859-1 西欧,Latin-1。
ISO-8859-5 ISO8859-5 很少使用的西里尔字符集(拉丁语/西里尔语)。
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

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

变更日志

版本 描述
8.1.0 flagsENT_COMPAT 更改为 ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401

示例

示例 #1 htmlspecialchars() 示例

<?php
$new
= htmlspecialchars("<a href='test'>Test</a>", ENT_QUOTES);
echo
$new; // &lt;a href=&#039;test&#039;&gt;Test&lt;/a&gt;
?>

注释

注意:

请注意,此函数不会翻译上述内容之外的任何内容。有关完整实体转换,请参见 htmlentities()

注意:

对于模棱两可的 flags 值,将应用以下规则

参见

添加注释

用户贡献的注释 21 个注释

75
Dave
11 年前
从 PHP 5.4 开始,它们将默认编码从“ISO-8859-1”更改为“UTF-8”。因此,如果您从 htmlspecialchars 或 htmlentities 获得 null

您只设置了
<?php
echo htmlspecialchars($string);
echo
htmlentities($string);
?>

您可以通过以下方式解决它
<?php
echo htmlspecialchars($string, ENT_COMPAT,'ISO-8859-1', true);
echo
htmlentities($string, ENT_COMPAT,'ISO-8859-1', true);
?>

在 Linux 上,您可以通过以下方式找到您需要修复的脚本

grep -Rl "htmlspecialchars\\|htmlentities" /path/to/php/scripts/
48
Mike Robinson
11 年前
不幸的是,据我所知,PHP 开发人员没有提供任何方法来设置 htmlspecialchars() 或 htmlentities() 使用的默认编码,即使他们在 PHP 5.4 中更改了默认编码(*为 PHP 开发人员鼓掌*)。为了节省人们尝试的时间,这不起作用

<?php
ini_set
('default_charset', $charset); // 不起作用。
?>

不幸的是,唯一不需要每次调用此函数时都显式提供第二个和第三个参数的方法(这会非常乏味)是编写自己的函数作为包装器

<?php
define
('CHARSET', 'ISO-8859-1');
define('REPLACE_FLAGS', ENT_COMPAT | ENT_XHTML);

function
html($string) {
return
htmlspecialchars($string, REPLACE_FLAGS, CHARSET);
}

echo
html("ñ"); // 可行
?>

您可以对 htmlentities() 执行相同的操作
8
Daniel Klein
2 年前
因为文档中说

int $flags = ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401

您可能会认为 ENT_HTML401 很重要。但正如注释中提到的,如果您没有指定文档类型,ENT_HTML401 是默认值。这是因为 ENT_HTML401 === 0。所以

int $flags = ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401



int $flags = ENT_QUOTES | ENT_SUBSTITUTE
23
Thomasvdbulk at gmail dot com
13 年前
我搜索了一段时间以找到一个脚本,它可以查看 HTML 标签和文本中放置的 < 和 > 之间的区别,
原因是我从数据库接收文本,
该文本是通过 HTML 表单插入的,包含文本和 HTML 标签,
文本可以包含 < 和 >,标签也可以,
使用 htmlspecialchars,您可以验证文本以使其符合 XHTML,
但您也会更改标签,例如 <b> 更改为 &lt;b&gt;,
因此我需要一个可以查看这两者之间区别的脚本...
但我找不到,所以我自己写了一个,
我还没有完全测试它,但我测试的部分工作完美!
仅供那些正在寻找类似内容的人使用,
它看起来可能很大,可以更轻松地完成,但它对我有用,所以我很高兴。

<?php
function fixtags($text){
$text = htmlspecialchars($text);
$text = preg_replace("/=/", "=\"\"", $text);
$text = preg_replace("/&quot;/", "&quot;\"", $text);
$tags = "/&lt;(\/|)(\w*)(\ |)(\w*)([\\\=]*)(?|(\")\"&quot;\"|)(?|(.*)?&quot;(\")|)([\ ]?)(\/|)&gt;/i";
$replacement = "<$1$2$3$4$5$6$7$8$9$10>";
$text = preg_replace($tags, $replacement, $text);
$text = preg_replace("/=\"\"/", "=", $text);
return
$text;
}
?>

一个例子

<?php
$string
= "
this is smaller < than this<br />
this is greater > than this<br />
this is the same = as this<br />
<a href=\"http://www.example.com/example.php?test=test\">This is a link</a><br />
<b>Bold</b> <i>italic</i> etc..."
;
echo
fixtags($string);
?>

将输出
this is smaller &lt; than this<br />
this is greater &gt; than this<br />
this is the same = as this<br />
<a href="http://www.example.com/example.php?test=test">This is a link</a><br />
<b>Bold</b> <i>italic</i> etc...

希望它对您有所帮助!!
17
Kenneth Kin Lum
15 年前
如果您只是想保护您的页面免受跨站点脚本 (XSS) 攻击,或者只是想在网页上显示 HTML 标签(例如,在页面上显示 <body>),那么使用 htmlspecialchars() 就足够了,并且比使用 htmlentities() 更好。一个小的区别是 htmlspecialchars() 比 htmlentities() 更快。更重要的是,当我们在代码中使用 htmlspecialchars($s) 时,它会自动与 UTF-8 字符串兼容。否则,如果我们使用 htmlentities($s),并且字符串 $s 中碰巧存在 UTF-8 编码的外国字符,那么 htmlentities() 将会把它弄乱,因为它会将字符串中的字节 0x80 到 0xFF 修改为像 &eacute; 这样的实体。(除非您专门为 htmlentities() 提供第二个参数和第三个参数,其中第三个参数为“UTF-8”)。

htmlspecialchars($s) 已经可以与 UTF-8 字符串一起工作的原因是,它将范围为 0x00 到 0x7F 的字节更改为 &lt; 等,同时保持范围为 0x80 到 0xFF 的字节不变。我们可能想知道 htmlspecialchars() 是否会意外地将 2 到 4 字节 UTF-8 字符中的任何字节更改为 &lt; 等。答案是,它不会。当 UTF-8 字符为 2 到 4 字节长时,此字符中的所有字节都在 0x80 到 0xFF 范围内。没有一个可以处于 0x00 到 0x7F 范围内。当 UTF-8 字符为 1 字节长时,它与 ASCII 相同,它是 7 位,从 0x00 到 0x7F。因此,当 UTF-8 字符为 1 字节长时,htmlspecialchars($s) 将完成其工作,而当 UTF-8 字符为 2 到 4 字节长时,htmlspecialchars($s) 将直接传递这些字节而不做任何改变。所以,无论 $s 是 ASCII、ISO-8859-1(Latin-1)还是 UTF-8,htmlspecialchars($s) 都将执行相同的操作。
1
Killian Leroux
2 年前
感谢 Thomasvdbulk 的解决方法,我想补充说明一下

当 HTML 包含一个链接标签,而链接标签之前没有换行符时,该脚本不起作用 :/

您的示例

<?php
$string
= "
this is smaller < than this<br />
this is greater > than this<br />
this is the same = as this<br />
<a href=\"http://www.example.com/example.php?test=test\">This is a link</a><br />
<b>Bold</b> <i>italic</i> etc..."
;
echo
fixtags($string);
?>

可以正常工作,但以下代码不起作用

<?php
$string
= "
this is smaller < than this<br />
this is greater > than this<br />
this is the same = as this<br /><a href=\"http://www.example.com/example.php?test=test\">This is a link</a><br />
<b>Bold</b> <i>italic</i> etc..."
;
echo
fixtags($string);
?>

所以我在开头添加了一个小的解决方法(在 htmlspecialchars 之前)

<?php
$text
= preg_replace('/<a/', "\r\n<a", $text);
?>

我不喜欢这种方法,但我没有找到其他解决方案... :/
10
Felix D.
10 年前
还有一件很重要的事情要提一下
htmlspecialchars(NULL)
返回空字符串而不是 NULL!
5
ASchmidt at Anamera dot net
3 年前
为了避免双重编码,除了 double_encode=false 之外,还必须指定 ENT_HTML5。

原因是,与文档相反,double_encode=false 不会无条件地全局阻止所有现有实体的双重编码。至关重要的是,它只会在对所选文档类型显式有效的那些字符实体中跳过双重编码!

由于 ENT_HTML5 引用了最广泛的字符实体列表,因此它是对现有字符实体最宽松的设置。

<?php
declare(strict_types=1);
$text = 'ampersand(&amp;), double quote(&quot;), single quote(&apos;), less than(&lt;), greater than(&gt;), numeric entities(&#x26;&#x22;&#x27;&#x3C;&#x3E;), HTML 5 entities(&plus;&comma;&excl;&dollar;&lpar;&ncedil;&euro;)';
$result3 = htmlspecialchars( $text, ENT_NOQUOTES | ENT_SUBSTITUTE, 'UTF-8', /*double_encode*/false );
$result4 = htmlspecialchars( $text, ENT_NOQUOTES | ENT_XML1 | ENT_SUBSTITUTE, 'UTF-8', /*double_encode*/false );
$result5 = htmlspecialchars( $text, ENT_NOQUOTES | ENT_XHTML | ENT_SUBSTITUTE, 'UTF-8', /*double_encode*/false );
$result6 = htmlspecialchars( $text, ENT_NOQUOTES | ENT_HTML5 | ENT_SUBSTITUTE, 'UTF-8', /*double_encode*/false );

echo
"<br />\r\nHTML 4.01:<br />\r\n", $result3,
"<br />\r\nXML 1:<br />\r\n", $result4,
"<br />\r\nXHTML:<br />\r\n", $result5,
"<br />\r\nHTML 5:<br />\r\n", $result6, "<br />\r\n";
?>

将产生

HTML 4.01(不会识别单引号,但会识别欧元)
ampersand(&), double quote("), single quote(&apos;), less than(<), greater than(>), numeric entities(&"'<>), HTML 5 entities(&plus;&comma;&excl;&dollar;&lpar;&ncedil;€)

XML 1(会识别单引号,但不会识别欧元)
ampersand(&), double quote("), single quote('), less than(<), greater than(>), numeric entities(&"'<>), HTML 5 entities(&plus;&comma;&excl;&dollar;&lpar;&ncedil;&euro;)

XHTML(识别单引号和欧元)
ampersand(&), double quote("), single quote('), less than(<), greater than(>), numeric entities(&"'<>), HTML 5 entities(&plus;&comma;&excl;&dollar;&lpar;&ncedil;€)

HTML 5(识别所有有效的字符实体)
ampersand(&), double quote("), single quote('), less than(<), greater than(>), numeric entities(&"'<>), HTML 5 entities(+,!$(ņ€)
11
ivan at lutrov dot com
13 年前
小心,“charset”参数是区分大小写的。这很不直观,而且没有实际意义,因为 HTML 规范实际上是相反的。
3
qshing1437 at hotmail dot com
5 年前
如果使用 htmlspecialchars() 对 HTML 属性进行转义,请确保对属性使用双引号而不是单引号。

例如:

> 使用单引号包裹
<?php
echo "<p title='" . htmlspecialchars("Hello\"s\'world") . "'">

// title 最终将变为 Hello"s\ 并且单引号之后的其余文本将被截断。
?>

> 使用双引号包裹
<?php
echo '<p title="' . htmlspecialchars("Hello\"s\'world") . '"'>

// title 将正确显示为 Hello"s'world
?>
7
Anonymous
14 年前
关于如何使用 htmlspecialchars() 和 htmlentities() 对表单中的用户输入进行过滤,以便稍后显示和/或存储到数据库中的一些说明…

1. 使用 htmlspecialchars() 对 html 输入标签的文本输入值进行过滤。例如:

echo '<input name=userdata type=text value="'.htmlspecialchars($data).'" />';


2. 使用 htmlentities() 对大多数其他类型的 html 标签的相同数据值进行过滤,例如:

echo '<p>'.htmlentities($data).'</p>';

3. 使用数据库转义字符串函数对数据库更新和插入的数据进行过滤,例如使用 postgresql:

pg_query($connection,"UPDATE datatable SET datavalue='".pg_escape_string($data)."'");


此策略似乎运行良好且一致,不会限制用户可能想键入和显示的任何内容,同时仍然提供对各种 html 和数据库转义序列注入的良好保护,否则这些注入可能会通过用户通过 html 表单提交其输入数据时故意或意外输入此类字符序列而引入。
4
Anonymous
14 年前
这可能看起来很明显,但它让我很沮丧。如果你尝试使用 htmlspecialchars 并设置 $charset 参数,并且你运行它的字符串实际上与你指定的字符集不同,那么你会得到一个空字符串,而不会有任何通知/警告/错误。

<?php

$ok_utf8
= "A valid UTF-8 string";
$bad_utf8 = "An invalid UTF-8 string";

var_dump(htmlspecialchars($bad_utf8, ENT_NOQUOTES, 'UTF-8')); // string(0) ""

var_dump(htmlspecialchars($ok_utf8, ENT_NOQUOTES, 'UTF-8')); // string(20) "A valid UTF-8 string"

?>

所以要确保你的字符集一致

<?php

$bad_utf8
= "An invalid UTF-8 string";

// 确保它确实是 UTF-8
$bad_utf8 = mb_convert_encoding($bad_utf8, 'UTF-8', mb_detect_encoding($bad_utf8));

var_dump(htmlspecialchars($bad_utf8, ENT_NOQUOTES, 'UTF-8')); // string(23) "An invalid UTF-8 string"

?>

我遇到这个问题是因为 Mac 用户提交了从程序中复制粘贴的帖子,其中包含奇怪的字符。
3
php dot net at orakio dot net
16 年前
我最近在探索一些代码时,发现它被用于使数据对“SQL”安全。

此函数不应该用于使数据对 SQL 安全(尽管为了防止网络钓鱼,它非常好)。

这是一个关于如何不使用此函数的示例

<?php
$username
= htmlspecialchars(trim("$_POST[username]"));

$uniqueuser = $realm_db->query("SELECT `login` FROM `accounts` WHERE `login` = '$username'");
?>

($_POST['username'] 上唯一的其他检查是确保它不是空的,它在对仅包含空格的名称进行 trim 后为空)

这里的问题是它被留给默认值,这允许使用单引号,这些单引号在 sql 查询中使用。打开 magic quotes 可能会解决它,但你不应该依赖 magic quotes,事实上你永远不应该使用它,而是修复代码。\ 没有被转义也会出现问题。即使使用 magic quotes,也会出现允许用户名超出限制以及给出一些非常奇怪的用户名的问题,因为它们要在 html 之外使用,这只是为使用 mysql 的另一个系统注册提供了前端。当然,在输出中使用它不会造成那个问题。

另一种方法是使用 ENT_QUOTE 或执行

<?php
$uniqueuser
= $realm_db->query('SELECT `login` FROM `accounts` WHERE `login` = "'.$username.'";');
?>

无论哪种方式,这些解决方案都不是最佳实践,也不是完全没有缺陷的。这个函数根本不应该以这种方式使用。

我希望这能防止新手错误地使用此函数(因为他们显然会这样做)。
3
ryan at ryano dot net
23 年前
实际上,如果您使用的是>= 4.0.5,理论上这应该更快(反正开销更小)。

$text = str_replace(array("&gt;", "&lt;", "&quot;", "&amp;"), array(">", "<", "\"", "&"), $text);
2
PoV
9 年前
注意您的源文件的编码!!!

这里的一些建议提到了您硬编码编码的解决方法。

<?php
echo htmlspecialchars('<b>Wörmann</b>'); // 为什么这不起作用?
?>

事实证明,这实际上可能是您的文本编辑器的错误。

从 PHP 5.4 开始,htmlspecialchars 现在默认使用 UTF-8 编码。也就是说,许多文本编辑器默认使用非 UTF 编码,例如 ISO-8859-1(即拉丁文-1)或 WIN-1252。如果将文件的编码更改为 UTF-8,上面的代码现在将起作用(即 ö 在 UTF-8 和 ISO-8859-1 中的编码方式不同,您需要 UTF-8 版本)。

确保您在 UTF-8 Unicode 模式下编辑!检查您的 UI 或手册了解如何将文件转换为 Unicode。确定如何在您的 UI 中查看当前文件编码也是一个好主意。
1
minder at ufive dot unibe dot ch
11 年前
问题

在许多 PHP 遗留产品中,函数 htmlspecialchars($string) 用于将 < 和 > 等字符以及引号转换为 HTML 实体。这避免了 HTML 标记和不对称引号情况的解释。

自从 PHP 5.4 以来,如果在函数中没有显式定义第三个参数作为字符集,则 htmlspecialchars($string) 中的 $string 将期望 utf8 字符。遗留产品主要使用 Latin1(别名 iso-8859-1),这使得函数 htmlspecialchars()、htmlentites() 和 html_entity_decode() 在 $string 中存在特殊字符(例如德语变音字母)时返回空字符串

PHP<5.4

echo htmlspecialchars('<b>Woermann</b>') // 输出:&lt;b&gt;Woermann&lt;b&gt;
echo htmlspecialchars('Wörmann') // 输出:&lt;b&gt;Wörmann&lt;b&gt;

PHP=5.4

echo htmlspecialchars('<b>Woermann</b>') // 输出:&lt;b&gt;Woermann&lt;b&gt;
echo htmlspecialchars('<b>Wörmann</b>') // 输出:空

三种替代解决方案

a) 不在 PHP 5.4 上运行遗留产品
b) 将代码中所有发现的地方从
htmlspecialchars($string) 和 *** 更改为
htmlspecialchars($string, ENT_COMPAT | ENT_HTML401, 'ISO-8859-1')
c) 用新的自建函数替换所有 htmlspecialchars() 和 ***

*** htmlentities() 和 html_entity_decode() 也是如此;

解决方案 c

1 在相关的遗留项目中进行搜索和替换
搜索:htmlspecialchars
替换为:htmlXspecialchars
搜索:htmlentities
替换为:htmlXentities
搜索:html_entity_decode
替换为:htmlX_entity_decode
2a 将以下三个函数复制粘贴到遗留项目中现有的已在所有地方包含的 PHP 文件中。(当然,该 PHP 文件每个请求只需包含一次,否则您将收到“重新声明函数致命错误”。)。

function htmlXspecialchars($string, $ent=ENT_COMPAT, $charset='ISO-8859-1') {
return htmlspecialchars($string, $ent, $charset);
}

function htmlXentities($string, $ent=ENT_COMPAT, $charset='ISO-8859-1') {
return htmlentities($string, $ent, $charset);
}

function htmlX_entity_decode($string, $ent=ENT_COMPAT, $charset='ISO-8859-1') {
return html_entity_decode($string, $ent, $charset);
}

或 2b 创建一个包含上面提到的三个函数的新 PHP 文件,例如,z. B. htmlXfunctions.inc.php 并将其包含在遗留产品中每个 PHP 文件的第一行,如下所示:require_once('htmlXfunctions.inc.php')。
-1
nachitox2000 [at] hotmail [dot] com
14 年前
我在西班牙语特殊字符方面遇到了问题。所以我认为使用 htmlspecialchars,但我的字符串也包含 HTML。
所以我使用了这个 :) 希望对您有所帮助

<?php
function htmlspanishchars($str)
{
return
str_replace(array("&lt;", "&gt;"), array("<", ">"), htmlspecialchars($str, ENT_NOQUOTES, "UTF-8"));
}
?>
-1
solar-energy
17 年前
另请参阅函数“urlencode()”,这对通过 URL 传递包含和号和其他特殊字符的文本很有用

(即文本被编码为从使用 GET 方法的表单发送)

例如

<?php
echo "<a href='foo.php?text=".urlencode("foo?&bar!")."'>link</a>";
?>

产生

<a href='foo.php?text=foo%3F%26bar%21'>link</a>

如果链接被点击,foo.php 中的 $_GET["text"] 将包含“foo?&bar!”
-2
_____ at luukku dot com
21 年前
人们,不要对最简单的字符串替换操作(用另一个常量字符串替换)使用 ereg_replace。
使用 str_replace。
-5
support at playnext dot ru
10 年前
对于那些在 PHP 5.4 之后 $encoding 参数的默认值更改为 UTF-8 后遇到问题的人。

如果您的旧非 UTF8 项目被破坏 - 请考虑
1. https://php.net/manual/en/function.override-function.php
2. https://php.net/manual/ru/function.runkit-function-redefine.php

这个想法是 - 您用自定义变体覆盖内置的 htmlspecialchars() 函数,该变体能够尊重非 UTF-8 默认编码。然后可以轻松地将这小段代码插入项目的开头。无需在全局范围内重写所有 htmlspecialchars() 条目。

我已经用这两种方法花了几个小时。变体 1 看起来不错,尤其是与 https://php.net/manual/en/function.rename-function.php 结合使用,因为它允许您只用修改后的默认参数调用原始 htmlspecialchars()。代码可能是这样的

<?php
rename_function
('htmlspecialchars', 'renamed_htmlspecialchars');
function
overriden_htmlspecialchars($string, $flags=NULL, $encoding='cp1251', $double_encode=true) {
$flags = $flags ? $flags : (ENT_COMPAT|ENT_HTML401);
return
renamed_htmlspecialchars($string, $flags, $encoding, $double_encode);
}
override_function('htmlspecialchars', '$string, $flags, $encoding, $double_encode', 'return overriden_htmlspecialchars($string, $flags, $encoding, $double_encode);');
?>

不幸的是,这对我来说没有正常工作 - 我的网站设法调用了覆盖的函数,但不是每次我重新加载页面时都会这样。此外,其他 PHP 网站在我的 Apache 服务器下崩溃,因为它们突然开始指责 htmlspecialchars() 未定义。我认为我需要花更多时间才能使它在线程/请求/站点/任何安全方面起作用。

所以我切换到 runkit(变体 2)。它对我有用,尽管即使在尝试 runkit_function_rename()+runkit_function_add() 之后,我也没有设法调用原始 htmlspecialchars() 函数。因此,作为一种快速解决方案,我决定改为调用 htmlentities()

<?php
function overriden_htmlspecialchars($string, $flags=NULL, $encoding='UTF-8', $double_encode=true) {
$flags = $flags ? $flags : (ENT_COMPAT|ENT_HTML401);
$encoding = $encoding ? $encoding : 'cp1251';
return
htmlentities($string, $flags, $encoding, $double_encode);
}
runkit_function_redefine('htmlspecialchars', '$string, $flags, $encoding, $double_encode', 'return overriden_htmlspecialchars($string, $flags, $encoding, $double_encode);');
?>

您可能能够实现更强大的覆盖函数。
祝你好运!
-11
匿名
19 年前
function htmlspecialchars_array($arr = array()) {
$rs = array();
while(list($key,$val) = each($arr)) {
if(is_array($val)) {
$rs[$key] = htmlspecialchars_array($val);
}
else {
$rs[$key] = htmlspecialchars($val, ENT_QUOTES);
}
}
return $rs;
}
To Top