Skip to content

9.6 实操:登录表单、注册表单

本实操将创建完整的登录表单和注册表单,包含表单验证、防XSS攻击等功能。

功能需求

  1. 注册表单:用户名、邮箱、密码、确认密码
  2. 登录表单:用户名/邮箱、密码
  3. 表单验证:非空、格式、长度验证
  4. 防XSS攻击:使用htmlspecialchars()
  5. 密码安全:使用password_hash()加密

实现代码

1. 数据库准备

首先,创建一个简单的用户表:

sql
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

2. 注册表单

php
<?php
// register.php
$errors = [];
$success = false;

// 模拟数据库连接
// 实际项目中应该使用真实的数据库连接
$users = [];

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // 非空验证
    if (empty($_POST['username'])) {
        $errors[] = '用户名不能为空';
    } else {
        $username = htmlspecialchars($_POST['username']);
    }
    
    if (empty($_POST['email'])) {
        $errors[] = '邮箱不能为空';
    } else if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
        $errors[] = '邮箱格式不正确';
    } else {
        $email = htmlspecialchars($_POST['email']);
    }
    
    if (empty($_POST['password'])) {
        $errors[] = '密码不能为空';
    } else if (strlen($_POST['password']) < 6) {
        $errors[] = '密码长度不能少于6位';
    } else {
        $password = $_POST['password'];
    }
    
    if (empty($_POST['confirm_password'])) {
        $errors[] = '确认密码不能为空';
    } else if ($_POST['password'] !== $_POST['confirm_password']) {
        $errors[] = '两次输入的密码不一致';
    }
    
    // 模拟用户名和邮箱唯一性检查
    if (empty($errors)) {
        // 实际项目中应该查询数据库检查
        $userExists = false;
        foreach ($users as $user) {
            if ($user['username'] === $username || $user['email'] === $email) {
                $userExists = true;
                break;
            }
        }
        
        if ($userExists) {
            $errors[] = '用户名或邮箱已存在';
        } else {
            // 加密密码
            $hashedPassword = password_hash($password, PASSWORD_DEFAULT);
            
            // 模拟添加用户
            $users[] = [
                'id' => count($users) + 1,
                'username' => $username,
                'email' => $email,
                'password' => $hashedPassword
            ];
            
            $success = true;
        }
    }
}
?>

<!DOCTYPE html>
<html>
<head>
    <title>用户注册</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 400px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }
        .form-container {
            background-color: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        h1 {
            text-align: center;
            color: #333;
        }
        .error {
            color: red;
            margin: 10px 0;
        }
        .success {
            color: green;
            margin: 10px 0;
        }
        input[type="text"],
        input[type="email"],
        input[type="password"] {
            width: 100%;
            padding: 10px;
            margin: 5px 0 15px 0;
            border: 1px solid #ddd;
            border-radius: 4px;
            box-sizing: border-box;
        }
        input[type="submit"] {
            width: 100%;
            padding: 10px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        input[type="submit"]:hover {
            background-color: #45a049;
        }
        .login-link {
            margin-top: 15px;
            text-align: center;
        }
    </style>
</head>
<body>
    <div class="form-container">
        <h1>用户注册</h1>
        
        <?php if (!empty($errors)): ?>
            <div class="error">
                <ul>
                    <?php foreach ($errors as $error): ?>
                        <li><?php echo $error; ?></li>
                    <?php endforeach; ?>
                </ul>
            </div>
        <?php endif; ?>
        
        <?php if ($success): ?>
            <div class="success">
                注册成功!<a href="login.php">立即登录</a>
            </div>
        <?php endif; ?>
        
        <form action="register.php" method="post">
            <label>用户名:</label>
            <input type="text" name="username" value="<?php echo isset($_POST['username']) ? htmlspecialchars($_POST['username']) : ''; ?>">
            
            <label>邮箱:</label>
            <input type="email" name="email" value="<?php echo isset($_POST['email']) ? htmlspecialchars($_POST['email']) : ''; ?>">
            
            <label>密码:</label>
            <input type="password" name="password">
            
            <label>确认密码:</label>
            <input type="password" name="confirm_password">
            
            <input type="submit" value="注册">
        </form>
        
        <div class="login-link">
            已有账号?<a href="login.php">登录</a>
        </div>
    </div>
</body>
</html>

3. 登录表单

php
<?php
// login.php
$errors = [];
$success = false;

// 模拟数据库连接
$users = [
    [
        'id' => 1,
        'username' => 'admin',
        'email' => 'admin@example.com',
        'password' => password_hash('123456', PASSWORD_DEFAULT)
    ]
];

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // 非空验证
    if (empty($_POST['login'])) {
        $errors[] = '用户名/邮箱不能为空';
    } else {
        $login = htmlspecialchars($_POST['login']);
    }
    
    if (empty($_POST['password'])) {
        $errors[] = '密码不能为空';
    } else {
        $password = $_POST['password'];
    }
    
    if (empty($errors)) {
        // 查找用户
        $user = null;
        foreach ($users as $u) {
            if ($u['username'] === $login || $u['email'] === $login) {
                $user = $u;
                break;
            }
        }
        
        if (!$user) {
            $errors[] = '用户不存在';
        } else if (!password_verify($password, $user['password'])) {
            $errors[] = '密码错误';
        } else {
            // 登录成功,实际项目中应该设置会话
            $success = true;
        }
    }
}
?>

<!DOCTYPE html>
<html>
<head>
    <title>用户登录</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 400px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }
        .form-container {
            background-color: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        h1 {
            text-align: center;
            color: #333;
        }
        .error {
            color: red;
            margin: 10px 0;
        }
        .success {
            color: green;
            margin: 10px 0;
        }
        input[type="text"],
        input[type="password"] {
            width: 100%;
            padding: 10px;
            margin: 5px 0 15px 0;
            border: 1px solid #ddd;
            border-radius: 4px;
            box-sizing: border-box;
        }
        input[type="submit"] {
            width: 100%;
            padding: 10px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        input[type="submit"]:hover {
            background-color: #45a049;
        }
        .register-link {
            margin-top: 15px;
            text-align: center;
        }
    </style>
</head>
<body>
    <div class="form-container">
        <h1>用户登录</h1>
        
        <?php if (!empty($errors)): ?>
            <div class="error">
                <ul>
                    <?php foreach ($errors as $error): ?>
                        <li><?php echo $error; ?></li>
                    <?php endforeach; ?>
                </ul>
            </div>
        <?php endif; ?>
        
        <?php if ($success): ?>
            <div class="success">
                登录成功!<a href="index.php">进入首页</a>
            </div>
        <?php endif; ?>
        
        <form action="login.php" method="post">
            <label>用户名/邮箱:</label>
            <input type="text" name="login" value="<?php echo isset($_POST['login']) ? htmlspecialchars($_POST['login']) : ''; ?>">
            
            <label>密码:</label>
            <input type="password" name="password">
            
            <input type="submit" value="登录">
        </form>
        
        <div class="register-link">
            还没有账号?<a href="register.php">注册</a>
        </div>
    </div>
</body>
</html>

代码解析

  1. 注册表单

    • 包含用户名、邮箱、密码、确认密码字段
    • 进行非空、格式、长度验证
    • 使用 htmlspecialchars() 防止 XSS 攻击
    • 使用 password_hash() 加密密码
    • 模拟用户名和邮箱唯一性检查
  2. 登录表单

    • 支持使用用户名或邮箱登录
    • 进行非空验证
    • 使用 password_verify() 验证密码
    • 模拟用户查找和验证过程

注意事项

  1. 数据库连接:实际项目中应该使用真实的数据库连接
  2. 密码安全:始终使用 password_hash() 加密密码,不要明文存储
  3. 会话管理:登录成功后应该设置会话,跟踪用户登录状态
  4. 错误处理:提供清晰的错误提示,帮助用户正确填写表单
  5. 安全性:除了防 XSS 外,还应该考虑 CSRF 防护等安全措施

练习

  1. 实现真实的数据库连接和用户存储
  2. 添加会话管理功能
  3. 实现密码重置功能
  4. 添加验证码功能,防止暴力破解

© 2026 编程马·菜鸟教程 版权所有