首页 / PHP 入门教程 / PHP 完整表单实例

PHP 入门教程

PHP 完整表单实例

本教程共 65 篇 · 第 25 篇 · 更新于 2026-07-24 · 约 5 分钟阅读

PHPPHP8表单实例用户注册密码哈希实战

25. PHP 完整表单实例

本节目标:通过用户注册表单的完整实战,学会把表单展示、数据验证、错误提示、安全处理整合到一个页面中。

前面两章分别讲了表单接收和验证。本章把它们串起来,做一个用户注册页面,让你看到真实项目的写法。

25.1 需求分析

注册表单需要收集以下信息:

字段规则
用户名必填,3-20 位字母数字下划线
邮箱必填,有效邮箱格式
密码必填,至少 6 位
确认密码必须与密码一致
性别单选,必填

25.2 单文件完整代码

把 HTML 表单和 PHP 处理放在同一个文件,提交后原地显示错误:

<?php
$errors = [];
$data   = [
    "username" => "",
    "email"    => "",
    "gender"   => "",
];

if ($_SERVER["REQUEST_METHOD"] === "POST") {
    $data["username"] = trim($_POST["username"] ?? "");
    $data["email"]    = trim($_POST["email"] ?? "");
    $data["gender"]   = $_POST["gender"] ?? "";
    $password         = $_POST["password"] ?? "";
    $confirm          = $_POST["confirm"] ?? "";

    // 1. 用户名验证
    if (empty($data["username"])) {
        $errors["username"] = "用户名不能为空";
    } elseif (!preg_match('/^[a-zA-Z0-9_]{3,20}$/', $data["username"])) {
        $errors["username"] = "用户名需为 3-20 位字母、数字或下划线";
    }

    // 2. 邮箱验证
    if (empty($data["email"])) {
        $errors["email"] = "邮箱不能为空";
    } elseif (!filter_var($data["email"], FILTER_VALIDATE_EMAIL)) {
        $errors["email"] = "邮箱格式不正确";
    }

    // 3. 密码验证
    if (strlen($password) < 6) {
        $errors["password"] = "密码至少 6 位";
    }
    if ($password !== $confirm) {
        $errors["confirm"] = "两次输入的密码不一致";
    }

    // 4. 性别验证
    if (empty($data["gender"])) {
        $errors["gender"] = "请选择性别";
    }

    // 5. 无错误则处理(如存入数据库)
    if (empty($errors)) {
        $hash = password_hash($password, PASSWORD_DEFAULT);
        // TODO: 将 $data 和 $hash 存入数据库
        echo "<p style='color:green'>注册成功!</p>";
        exit;
    }
}

function e(string $text): string {
    return htmlspecialchars($text, ENT_QUOTES, "UTF-8");
}
?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>用户注册</title>
    <style>
        .error { color: red; font-size: 14px; }
        input[type="text"], input[type="email"], input[type="password"] { width: 200px; }
    </style>
</head>
<body>
    <h2>用户注册</h2>
    <form method="post" action="">
        <p>
            用户名:<br>
            <input type="text" name="username" value="<?= e($data['username']) ?>">
            <span class="error"><?= $errors['username'] ?? '' ?></span>
        </p>
        <p>
            邮箱:<br>
            <input type="email" name="email" value="<?= e($data['email']) ?>">
            <span class="error"><?= $errors['email'] ?? '' ?></span>
        </p>
        <p>
            密码:<br>
            <input type="password" name="password">
            <span class="error"><?= $errors['password'] ?? '' ?></span>
        </p>
        <p>
            确认密码:<br>
            <input type="password" name="confirm">
            <span class="error"><?= $errors['confirm'] ?? '' ?></span>
        </p>
        <p>
            性别:<br>
            <label><input type="radio" name="gender" value="male"
                <?= $data['gender'] === 'male' ? 'checked' : '' ?>></label>
            <label><input type="radio" name="gender" value="female"
                <?= $data['gender'] === 'female' ? 'checked' : '' ?>></label>
            <span class="error"><?= $errors['gender'] ?? '' ?></span>
        </p>
        <p><input type="submit" value="立即注册"></p>
    </form>
</body>
</html>
Note

使用 $_SERVER["REQUEST_METHOD"] 判断 POST,确保首次访问页面时不执行验证逻辑。

25.3 保留用户输入的技巧

表单验证失败后,应该保留用户已填内容,只清空密码字段:

// 文本框保留值
<input type="text" name="username" value="<?= e($data['username']) ?>">

// 单选按钮保持选中
<input type="radio" name="gender" value="male" <?= $data['gender'] === 'male' ? 'checked' : '' ?>>

// 密码框不保留值(安全考虑)
<input type="password" name="password">

25.4 密码的安全存储

注册时千万不要明文存储密码。PHP 提供了 password_hash()(详见第 42 章安全基础中的密码存储章节):

<?php
$password = "user123456";
$hash = password_hash($password, PASSWORD_DEFAULT);

// $hash 存入数据库
// 验证时用 password_verify($input, $hash)
Tip

PASSWORD_DEFAULT 在 PHP 8.x 默认使用 bcrypt,未来会自动升级到更安全的算法,建议始终用它。

25.5 登录表单简化版

登录只需要用户名和密码,逻辑更简单:

<?php
$err = "";

if ($_SERVER["REQUEST_METHOD"] === "POST") {
    $user = trim($_POST["user"] ?? "");
    $pass = $_POST["pass"] ?? "";

    // 假设从数据库取出的哈希值为 $hashFromDb
    $hashFromDb = "$2y$10$..."; // 示例

    if ($user === "" || $pass === "") {
        $err = "请填写完整";
    } elseif (!password_verify($pass, $hashFromDb)) {
        $err = "用户名或密码错误";
    } else {
        echo "登录成功!";
        exit;
    }
}
?>

<form method="post">
    <input type="text" name="user" placeholder="用户名"><br>
    <input type="password" name="pass" placeholder="密码"><br>
    <span style="color:red"><?= $err ?></span><br>
    <input type="submit" value="登录">
</form>
Note

登录失败时提示”用户名或密码错误”,不要具体告诉用户是哪个错了,防止被枚举。


来源:参考了 runoob「PHP 完整表单实例」、w3cschool「PHP 完整表单实例」等,改写后所得。