PHP 表单验证
                           
天天向上
发布: 2025-03-19 22:03:01

原创
986 人浏览过

表单验证是 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)
防止 XSShtmlspecialchars($data)
防止 CSRF$_SESSION['csrf_token']
防止重复提交header("Location: success.php")

📌 推荐阅读

更多详细内容请关注其他相关文章!

发表回复 0

Your email address will not be published. Required fields are marked *