HTML 编码是在处理用户提供的数据时试图在 PHP Web 应用程序中防止跨站脚本 XSS。本教程将教你如何使用 htmlentities()
、htmlspecialchars()
和自定义方法对数据进行编码。
使用 htmlspecialchars()
编码
PHP htmlspecialchars()
是一个内置函数,可以将特殊字符转换为 HTML 实体。语法如下:
htmlspecialchars( $string, $flags, $encoding, $double_encode )
参数说明:
-
$string
: 输入字符串 -
$flags
:指示函数应如何处理字符串中的引号的标志 -
$encoding
:指定函数使用的编码。该参数是可选的 -
$double_encode
:一个布尔属性,指示 PHP 是否将对现有实体进行编码。如果将其设置为 false,PHP 将不会对现有实体进行编码
像所有函数一样,htmlspecialchars()
返回一个值。它的值是转换后的字符串。但是,如果函数认为该字符串无效,它将返回一个空字符串。
下一个示例展示了如何使用 htmlspecialchars()
转换字符串。你会观察到该函数未与任何标志一起使用。
<?php
$stringToEncode = "A <b>bold text</b> a'nd á <script>alert();</script> tag";
$encodedString = htmlspecialchars($stringToEncode);
echo $encodedString;
?>
输出:
A <b>bold text</b> a'nd á <script>alert();</script> tag
当你查看网页的源代码时,你会发现撇号和 á 字符未编码:
A <b>bold text</b> a'nd á <script>alert();</script> tag
现在,如果你向 htmlspecialchars()
提供标志和编码格式,撇号会被编码,但 á
不会。
<?php
$stringToEncode = "A <b>bold text</b> a'nd á <script>alert();</script> tag";
$encodedString = htmlspecialchars($stringToEncode, ENT_QUOTES, 'UTF-8');
echo $encodedString;
?>
输出:
A <b>bold text</b> a'nd á <script>alert();</script> tag
页面的查看源代码显示浏览器将撇号编码为'
:
A <b>bold text</b> a'nd á <script>alert();</script> tag
用 htmlentities()
编码
htmlentites()
也是一个内置的 PHP 函数。使用 htmlentities()
,所有适用的字符都将转换为 HTML 实体。它的语法如下:
htmlentities( $string, $flags, $encoding, $double_encode )
下面是对参数的解释:
-
$string
: 输入字符串 -
$flags
:指示函数应如何处理字符串中的引号的标志 -
$encoding
:指定函数使用的编码。该参数是可选的 -
$double_encode
:一个布尔属性,指示 PHP 是否将对现有实体进行编码。如果将其设置为 false,PHP 将不会对现有实体进行编码
此函数的返回值是编码字符串。
以下是使用 htmlentities()
转换字符串的示例。这里 htmlentities()
不与任何标志一起使用。
<?php
$stringToEncode = "A <b>bold text</b> ánd a <script>alert();</script> tag's";
$ecodedString = htmlentities($stringToEncode);
echo $ecodedString;
?>
输出:
A <b>bold text</b> ánd a <script>alert();</script> tag's
该页面的视图源显示该函数对á字符进行了编码,没有任何标志,但撇号没有编码。
A <b>bold text</b> ánd a <script>alert();</script> tag's
对代码的更改将允许函数对撇号进行编码。
<?php
$stringToEncode = "A <b>bold text</b> ánd a <script>alert();</script> tag's";
$ecodedString = htmlentities($stringToEncode, ENT_QUOTES, 'UTF-8');
echo $ecodedString;
?>
输出:
A <b>bold text</b> ánd a <script>alert();</script> tag's
查看页面来源:
A <b>bold text</b> ánd a <script>alert();</script> tag's
使用 htmlentities()
和 HTML5 编码进行编码
当字符串中有非英文字符时,可以使用 HTML 5
标志和 UTF-8
编码。
HTML5
标志指示函数将字符串视为 HTML5,而 UTF-8
标志允许函数理解任何标准 Unicode 字符。
以下是如何使用带有 HTML5 标志和 UTF-8 编码的 htmlentities()
的示例:
<?php
$stringToEncode = "àéò ©€ ♣♦ ↠ ↔↛ āžšķūņ ↙ ℜ℞ ∀∂∋ rūķīš ○";
$ecodedString = htmlentities($stringToEncode, ENT_HTML5, 'UTF-8');
echo $ecodedString;
?>
查看页面来源:
àéò ©€ ♣♦
↠ ↔↛ āžš
ķūņ ↙ ℜ℞ ∀∂∋
rūķīš ○
使用自定义方法编码
如果你想滚动编码方案,自定义方法可以派上用场。此方法将获取你的输入字符串并应用一些字符串操作。最后,你会得到一个编码字符串。
下面的 HTML 有一个文本区域和一个提交按钮。表单 action
指向一个文件,该文件将对传递到表单输入的字符串进行编码。
<main>
<h1>Enter and HTML code and click the submit button</h1>
<form action='encodedoutput.php' method='post'>
<div class="form-row">
<textarea rows='15' cols='50' name='texttoencode' required></textarea>
</div>
<div class="form-row">
<input type='submit'>
</div>
</form>
</main>
下一个代码块是执行编码的 PHP 代码。将其保存为 encodedoutput.php
。
<?php
if (isset($_POST['texttoencode']) && !empty($_POST)) {
// Check for empty text
if ($_POST['texttoencode'] == "") {
echo "Invalid text";
die();
}
$inputHTML = bin2hex($_POST['texttoencode']);
$spiltHTML = chunk_split($inputHTML, 2 ,"%");
$HTMLStringLength = strlen($spiltHTML);
$HTMLSubLength = $HTMLStringLength - 1;
$HTMLSubString = substr($spiltHTML,'0', $HTMLSubLength);
$encodedOutput="<script>document.write(unescape('%$HTMLSubString'));</script>";
} else {
echo "Not allowed";
die();
}
?>
<textarea rows='15' cols='60'>
<?php
if ($encodedOutput) {
echo $encodedOutput;
} else {
echo "";
die();
}
?>
</textarea>
<script>alert("Hello world");</alert>
的示例输出:
<script>document.write(unescape('%3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28%22%48%65%6c%6c%6f%20%77%6f%72%6c%64%22%29%3b%3c%2f%61%6c%65%72%74%3e'));</script>