PHP 表单验证
PHP 表单验证中文讲解
什么是 PHP 表单验证?
PHP 表单验证是指在服务器端对用户通过 HTML 表单提交的数据进行检查和处理,以确保数据的完整性、有效性和安全性。验证可以防止无效数据、恶意输入(如 SQL 注入或 XSS 攻击)以及不符合业务逻辑的数据进入系统。表单验证是 PHP Web 开发中的关键环节,广泛应用于用户注册、登录、搜索等场景。
为什么需要表单验证?
- 数据完整性:确保必填字段不为空,数据格式正确(如邮箱、电话)。
- 安全性:防止恶意输入,如脚本注入或 SQL 注入。
- 用户体验:通过清晰的错误提示帮助用户纠正输入错误。
- 业务逻辑:确保数据符合应用需求(如年龄限制、唯一用户名)。
核心验证方法
PHP 提供多种内置函数和工具来验证表单数据,结合逻辑判断实现健壮的验证流程。以下是常见验证方法和场景:
- 检查必填字段
使用empty()
或isset()
判断字段是否为空:
<?php
if (empty($_POST['name'])) {
$errors[] = "姓名不能为空";
}
- 验证数据格式
使用filter_var()
或正则表达式验证特定格式:
- 邮箱格式:
php $email = $_POST['email']; if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { $errors[] = "无效的邮箱格式"; }
- 数字范围:
php $age = $_POST['age']; if (!filter_var($age, FILTER_VALIDATE_INT) || $age < 18 || $age > 120) { $errors[] = "年龄必须是 18-120 之间的整数"; }
- 清理输入数据
使用filter_var()
或htmlspecialchars()
清理输入,防止 XSS 攻击:
$name = filter_var($_POST['name'], FILTER_SANITIZE_STRING);
$name = htmlspecialchars($name, ENT_QUOTES, 'UTF-8');
- 正则表达式验证
检查复杂格式,如电话号码:
$phone = $_POST['phone'];
if (!preg_match("/^1[3-9]\d{9}$/", $phone)) {
$errors[] = "无效的手机号码";
}
- 文件上传验证
检查文件类型、大小等:
if (isset($_FILES['file']) && $_FILES['file']['error'] === UPLOAD_ERR_OK) {
$allowed = ['jpg', 'png'];
$ext = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
if (!in_array($ext, $allowed)) {
$errors[] = "只允许 JPG 或 PNG 文件";
}
if ($_FILES['file']['size'] > 2 * 1024 * 1024) {
$errors[] = "文件大小不能超过 2MB";
}
}
完整示例:表单验证
以下是一个完整的用户注册表单验证示例,包括 HTML 和 PHP 代码:
- HTML 表单 (
register.html
):
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户注册</title>
</head>
<body>
<form action="register.php" method="post">
<label for="name">姓名:</label>
<input type="text" id="name" name="name" value="<?php echo isset($_POST['name']) ? htmlspecialchars($_POST['name']) : ''; ?>">
<br>
<label for="email">邮箱:</label>
<input type="email" id="email" name="email" value="<?php echo isset($_POST['email']) ? htmlspecialchars($_POST['email']) : ''; ?>">
<br>
<label for="password">密码:</label>
<input type="password" id="password" name="password">
<br>
<input type="submit" value="注册">
</form>
</body>
</html>
- PHP 验证脚本 (
register.php
):
<?php
// 初始化错误数组
$errors = [];
$data = [];
// 检查请求方法
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 获取并清理输入
$name = filter_var($_POST['name'] ?? '', FILTER_SANITIZE_STRING);
$email = filter_var($_POST['email'] ?? '', FILTER_SANITIZE_EMAIL);
$password = $_POST['password'] ?? '';
// 验证必填字段
if (empty($name)) {
$errors[] = "姓名不能为空";
}
if (empty($email)) {
$errors[] = "邮箱不能为空";
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = "无效的邮箱格式";
}
if (empty($password)) {
$errors[] = "密码不能为空";
} elseif (strlen($password) < 6) {
$errors[] = "密码长度至少为 6 位";
}
// 如果没有错误,处理数据
if (empty($errors)) {
// 模拟保存到数据库(使用 PDO 防 SQL 注入)
try {
$pdo = new PDO("mysql:host=localhost;dbname=test", "user", "pass");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->prepare("INSERT INTO users (name, email, password) VALUES (:name, :email, :password)");
$stmt->execute([
'name' => $name,
'email' => $email,
'password' => password_hash($password, PASSWORD_DEFAULT) // 加密密码
]);
echo "注册成功!";
} catch (PDOException $e) {
$errors[] = "数据库错误: " . $e->getMessage();
}
}
}
// 显示错误
if (!empty($errors)) {
echo "<ul>";
foreach ($errors as $error) {
echo "<li>$error</li>";
}
echo "</ul>";
}
?>
安全性注意事项
- 防止 XSS 攻击:
- 使用
htmlspecialchars()
转义输出。 - 清理输入数据:
filter_var($input, FILTER_SANITIZE_STRING)
。
- 防止 SQL 注入:
- 使用 PDO 或 MySQLi 的预处理语句,避免直接拼接 SQL 查询。
- 示例:
php $stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email"); $stmt->execute(['email' => $email]);
- CSRF 保护:
- 添加 CSRF 令牌验证:
php session_start(); if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); } ?> ¨K17K <?php if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) { die("CSRF 验证失败"); }
- 密码安全:
- 使用
password_hash()
加密密码,验证时用password_verify()
:php $password = $_POST['password']; $hashed = password_hash($password, PASSWORD_DEFAULT); // 验证 if (password_verify($password, $hashed)) { echo "密码正确"; }
最佳实践
- 集中验证逻辑:将验证规则封装在函数或类中,提高复用性:
function validateEmail($email) {
return filter_var($email, FILTER_VALIDATE_EMAIL) ? true : false;
}
- 回显输入:验证失败时,使用
htmlspecialchars()
回显用户输入,避免数据丢失ਸ
System: 丢失,防止 XSS 攻击。
- 错误提示友好:提供具体的错误信息,引导用户更正输入。
- 客户端验证结合:在客户端使用 JavaScript 进行初步验证,减轻服务器负担,但不要完全依赖。
- 使用过滤器:优先使用 PHP 的
filter_var()
函数,简单高效。 - 表单结构:确保
name
属性唯一,方便 PHP 获取数据。
参考资源
- PHP 官方手册 – 过滤函数:
filter_var
等函数说明。 - 菜鸟教程 – PHP 表单验证:初学者友好教程。
- OWASP 安全指南:Web 应用安全最佳实践。
总结
PHP 表单验证是确保用户输入安全、有效和符合业务逻辑的关键步骤。通过检查必填字段、验证数据格式、清理输入和防范安全威胁(如 XSS、SQL 注入、CSRF),开发者可以构建健壮的 Web 应用。结合客户端验证和最佳实践,表单处理既安全又用户友好,是 PHP 开发的核心技能。