PHP 表单验证
本章及后续章节将展示如何使用 PHP 验证表单数据。
PHP 表单验证
处理 PHP 表单时请考虑安全性!
这些页面将展示如何安全地处理 PHP 表单。正确验证表单数据对于保护您的表单免受黑客和垃圾邮件发送者的侵害至关重要!
本章中我们将使用的 HTML 表单包含各种输入字段:必填和选填的文本字段、单选按钮以及一个提交按钮。
上述表单的验证规则如下:
字段 | 验证规则 |
---|---|
名称 | 必填。+ 只能包含字母和空格 |
电子邮件 | 必填。+ 必须包含有效的电子邮件地址(带 @ 和 .) |
网站 | 选填。如果存在,则必须包含有效的 URL |
注释 | 选填。多行输入字段(textarea) |
性别 | 必填。必须选择一项 |
首先,我们来看表单的纯 HTML 代码。
文本字段
Name、email 和 website 字段是文本输入元素,comment 字段是 textarea。
HTML 代码如下:
Name: <input type="text" name="name">
E-mail: <input type="text" name="email">
Website: <input type="text" name="website">
Comment: <textarea name="comment" rows="5" cols="40"></textarea>
单选按钮
Gender 字段是单选按钮,HTML 代码如下:
Gender:
<input type="radio" name="gender" value="female">Female
<input type="radio" name="gender" value="male">Male
<input type="radio" name="gender" value="other">Other
表单元素
表单的 HTML 代码如下:
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
当表单提交时,表单数据将通过 method="post" 发送。
什么是 $_SERVER["PHP_SELF"]
变量?$_SERVER["PHP_SELF"]
是一个超全局变量,它返回当前执行脚本的文件名。
因此,$_SERVER["PHP_SELF"]
将提交的表单数据发送到脚本本身,而不是跳转到另一个页面。这样,用户将在同一页面上收到错误消息。
什么是 htmlspecialchars()
函数?htmlspecialchars()
函数将特殊字符转换为 HTML 实体。这意味着它会将 `<` 和 `>` 等 HTML 字符替换为 `<` 和 `>`。这可以防止攻击者通过在表单中注入 HTML 或 Javascript 代码(跨站脚本攻击)来利用代码。
警告!
$_SERVER["PHP_SELF"]
变量可能被黑客利用!
如果在页面中使用 PHP_SELF,用户就可以输入斜杠 `/`,然后是一些跨站脚本(XSS)命令来执行。
跨站脚本(XSS)是一种通常在 Web 应用程序中发现的计算机安全漏洞。XSS 允许攻击者将客户端脚本注入到其他用户查看的网页中。
假设我们在一个名为“test_form.php”的页面中有一个如下表单:
<form method="post" action="<?php echo $_SERVER["PHP_SELF"];?>">
现在,如果用户在地址栏中输入普通 URL,如“http://www.example.com/test_form.php”,则上述代码将被翻译为:
<form method="post" action="test_form.php">
到目前为止,一切正常。
但是,请考虑用户在地址栏中输入以下 URL:
http://www.example.com/test_form.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E
在这种情况下,上述代码将被翻译为:
<form method="post" action="test_form.php/"><script>alert('hacked')</script>
这段代码添加了一个脚本标签和一个 alert 命令。当页面加载时,JavaScript 代码将被执行(用户将看到一个 alert 框)。这只是一个简单无害的示例,说明了 PHP_SELF 变量可能被利用的方式。
请注意,任何 JavaScript 代码都可以添加到 <script> 标签中!黑客可以重定向用户到一个另一个服务器上的文件,而该文件可能包含恶意代码,可以更改全局变量或将表单提交到另一个地址以保存用户数据,例如。
如何避免 $_SERVER["PHP_SELF"] 漏洞?
可以使用 htmlspecialchars()
函数来避免 $_SERVER["PHP_SELF"]
漏洞。
表单代码应如下所示:
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
htmlspecialchars()
函数将特殊字符转换为 HTML 实体。现在,如果用户尝试利用 PHP_SELF 变量,将产生以下输出:
<form method="post" action="test_form.php/"><script>alert('hacked')</script>">
漏洞尝试失败,没有造成任何损害!
使用 PHP 验证表单数据
我们将做的第一件事是将所有变量通过 PHP 的 htmlspecialchars()
函数。
当我们使用 htmlspecialchars()
函数时;如果用户尝试在文本字段中提交以下内容:
<script>location.href('http://www.hacked.com')</script>
—— 这将不会被执行,因为它将被保存为 HTML 转义的代码,如下所示:
<script>location.href('http://www.hacked.com')</script>
现在,代码可以安全地显示在页面上或嵌入到电子邮件中。
当用户提交表单时,我们还将执行另外两项操作:
- 从用户输入数据中删除不必要的字符(额外空格、制表符、换行符)(使用 PHP 的
trim()
函数) - 从用户输入数据中删除反斜杠 `\`(使用 PHP 的
stripslashes()
函数)
下一步是创建一个函数来为我们完成所有检查(这比一遍又一遍地编写相同的代码要方便得多)。
我们将该函数命名为 test_input()
。
现在,我们可以使用 test_input()
函数检查每个 $_POST
变量,脚本如下:
示例
// define variables and set to empty values
$name = $email = $gender = $comment = $website = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$name = test_input($_POST["name"]);
$email = test_input($_POST["email"]);
$website = test_input($_POST["website"]);
$comment = test_input($_POST["comment"]);
$gender = test_input($_POST["gender"]);
}
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
运行示例 »
请注意,在脚本开头,我们使用 $_SERVER["REQUEST_METHOD"]
检查表单是否已提交。如果 REQUEST_METHOD
是 POST
,则表示表单已提交——应进行验证。如果尚未提交,则跳过验证并显示一个空白表单。
然而,在上面的示例中,所有输入字段都是可选的。即使用户不输入任何数据,脚本也能正常工作。
下一步是使输入字段成为必填项,并在需要时创建错误消息。