表单验证是 Web 开发中的重要环节,它确保用户输入的数据符合预期,并防止 SQL 注入、XSS(跨站脚本攻击)和 CSRF(跨站请求伪造) 等安全风险。
1️⃣ 表单验证的重要性
✅ 防止空值提交:避免用户提交空表单。
✅ 确保数据格式正确:如邮箱、电话号码、URL 格式等。
✅ 防止 XSS 和 SQL 注入:确保用户输入数据不会被用于恶意攻击。
✅ 提高用户体验:减少用户提交错误,提高表单可用性。
2️⃣ HTML 表单
首先,创建一个带有 姓名、邮箱、网址、年龄 和 留言 的 HTML 表单:
<form action="validate.php" method="post">
<label for="name">姓名:</label>
<input type="text" name="name" id="name">
<label for="email">邮箱:</label>
<input type="text" name="email" id="email">
<label for="website">网址:</label>
<input type="text" name="website" id="website">
<label for="age">年龄:</label>
<input type="text" name="age" id="age">
<label for="comment">留言:</label>
<textarea name="comment" id="comment"></textarea>
<input type="submit" value="提交">
</form>
3️⃣ PHP 表单验证代码
创建 validate.php 进行服务器端验证:
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// 1️⃣ 定义变量
$name = $email = $website = $age = $comment = "";
$errors = [];
// 2️⃣ 姓名验证(必填,至少2个字符)
if (empty($_POST["name"])) {
$errors[] = "姓名不能为空!";
} else {
$name = test_input($_POST["name"]);
if (!preg_match("/^[a-zA-Z\x{4e00}-\x{9fa5} ]+$/u", $name)) {
$errors[] = "姓名只能包含字母和空格!";
}
}
// 3️⃣ 邮箱验证
if (empty($_POST["email"])) {
$errors[] = "邮箱不能为空!";
} else {
$email = test_input($_POST["email"]);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = "无效的邮箱格式!";
}
}
// 4️⃣ 网址验证
if (!empty($_POST["website"])) {
$website = test_input($_POST["website"]);
if (!filter_var($website, FILTER_VALIDATE_URL)) {
$errors[] = "无效的网址!";
}
}
// 5️⃣ 年龄验证(必须是数字)
if (!empty($_POST["age"])) {
$age = test_input($_POST["age"]);
if (!filter_var($age, FILTER_VALIDATE_INT)) {
$errors[] = "年龄必须是整数!";
}
}
// 6️⃣ 留言(防止 XSS)
if (!empty($_POST["comment"])) {
$comment = test_input($_POST["comment"]);
}
// 7️⃣ 统一数据清理函数
function test_input($data) {
$data = trim($data); // 去掉前后空格
$data = stripslashes($data); // 删除反斜杠
$data = htmlspecialchars($data); // 转换 HTML 实体,防止 XSS
return $data;
}
// 8️⃣ 显示结果或错误信息
if (empty($errors)) {
echo "✅ 验证成功!<br>";
echo "姓名: $name <br>";
echo "邮箱: $email <br>";
echo "网址: $website <br>";
echo "年龄: $age <br>";
echo "留言: $comment <br>";
} else {
foreach ($errors as $error) {
echo "❌ $error <br>";
}
}
}
?>
4️⃣ 详细解析
✅ $_SERVER["REQUEST_METHOD"] == "POST":确保数据是 POST 提交的。
✅ empty($_POST["name"]):检查是否为空。
✅ preg_match("/^[a-zA-Z\x{4e00}-\x{9fa5} ]+$/u", $name):检查姓名是否只包含 字母、汉字和空格。
✅ filter_var($email, FILTER_VALIDATE_EMAIL):检查邮箱格式。
✅ filter_var($website, FILTER_VALIDATE_URL):检查网址是否有效。
✅ filter_var($age, FILTER_VALIDATE_INT):确保年龄是整数。
✅ htmlspecialchars():防止 XSS(跨站脚本攻击)。
✅ stripslashes():去掉反斜杠,避免 SQL 注入。
✅ trim():去掉前后空格,防止用户误输入空格。
5️⃣ 防止 CSRF(跨站请求伪造)
在 HTML 表单中添加 CSRF 令牌:
<?php
session_start();
$_SESSION["csrf_token"] = bin2hex(random_bytes(32));
?>
<form action="validate.php" method="post">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
<input type="text" name="name">
<input type="submit" value="提交">
</form>
在 validate.php 验证 CSRF 令牌:
session_start();
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die("CSRF 验证失败!");
}
✅ 原理:每个表单提交时附带 csrf_token,防止恶意网站伪造请求。
6️⃣ 防止表单重复提交
用户刷新页面会导致表单重复提交,可以使用 header("Location: success.php") 解决:
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// 处理数据
header("Location: success.php"); // 重定向,避免重复提交
exit;
}
✅ 原理:提交后重定向到 success.php,刷新不会重复提交数据。
7️⃣ 使用 JavaScript 进行前端验证
虽然服务器端验证是必须的,但可以使用 JavaScript 进行前端验证,提高用户体验:
<script>
function validateForm() {
let name = document.getElementById("name").value;
let email = document.getElementById("email").value;
if (name.trim() === "") {
alert("姓名不能为空!");
return false;
}
let emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!email.match(emailPattern)) {
alert("请输入有效的邮箱!");
return false;
}
return true;
}
</script>
✅ 前端验证可以 减少服务器负担,但不能替代服务器端验证。
8️⃣ 总结
| 验证类型 | 方法 |
|---|---|
| 必填字段 | empty($value) |
| 字符限制 | preg_match("/正则/") |
| 邮箱格式 | filter_var($email, FILTER_VALIDATE_EMAIL) |
| URL 格式 | filter_var($website, FILTER_VALIDATE_URL) |
| 数字格式 | filter_var($age, FILTER_VALIDATE_INT) |
| 防止 XSS | htmlspecialchars($data) |
| 防止 CSRF | $_SESSION['csrf_token'] |
| 防止重复提交 | header("Location: success.php") |
📌 推荐阅读
更多详细内容请关注其他相关文章!