你知道如何从零开始用PHP搭建一个完整的用户注册与登录系统吗

wen PHP项目 43

本文目录导读:

你知道如何从零开始用PHP搭建一个完整的用户注册与登录系统吗

  1. 项目结构
  2. 数据库设置
  3. 配置文件
  4. 功能函数文件
  5. 会话管理
  6. 注册页面
  7. 登录页面
  8. 仪表盘页面(需要登录)
  9. 退出登录
  10. CSS样式
  11. 首页(可选)
  12. 安全性增强建议
  13. 运行测试

我来详细说明如何从零开始用PHP搭建一个完整的用户注册与登录系统。

项目结构

user-system/
├── config/
│   └── database.php
├── css/
│   └── style.css
├── includes/
│   ├── functions.php
│   └── session.php
├── register.php
├── login.php
├── dashboard.php
├── logout.php
└── index.php

数据库设置

首先创建MySQL数据库:

CREATE DATABASE user_system;
USE user_system;
CREATE TABLE users (
    id INT(11) 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,
    last_login TIMESTAMP NULL,
    is_active TINYINT(1) DEFAULT 1
);

配置文件

config/database.php

<?php
define('DB_HOST', 'localhost');
define('DB_USER', 'root');
define('DB_PASS', '');
define('DB_NAME', 'user_system');
try {
    $pdo = new PDO(
        "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME,
        DB_USER,
        DB_PASS,
        [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES => false
        ]
    );
} catch(PDOException $e) {
    die("连接失败: " . $e->getMessage());
}
?>

功能函数文件

includes/functions.php

<?php
// 密码哈希
function hashPassword($password) {
    return password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
}
// 验证密码
function verifyPassword($password, $hash) {
    return password_verify($password, $hash);
}
// 验证输入
function validateInput($data) {
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data);
    return $data;
}
// 检查用户名
function checkUsername($username) {
    global $pdo;
    $stmt = $pdo->prepare("SELECT id FROM users WHERE username = ?");
    $stmt->execute([$username]);
    return $stmt->rowCount() > 0;
}
// 检查邮箱
function checkEmail($email) {
    global $pdo;
    $stmt = $pdo->prepare("SELECT id FROM users WHERE email = ?");
    $stmt->execute([$email]);
    return $stmt->rowCount() > 0;
}
// 获取用户信息
function getUserById($id) {
    global $pdo;
    $stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
    $stmt->execute([$id]);
    return $stmt->fetch();
}
// 更新最后登录时间
function updateLastLogin($userId) {
    global $pdo;
    $stmt = $pdo->prepare("UPDATE users SET last_login = NOW() WHERE id = ?");
    $stmt->execute([$userId]);
}
// 错误消息
function showError($message) {
    return '<div class="alert alert-error">' . $message . '</div>';
}
// 成功消息
function showSuccess($message) {
    return '<div class="alert alert-success">' . $message . '</div>';
}
?>

会话管理

includes/session.php

<?php
session_start();
function isLoggedIn() {
    return isset($_SESSION['user_id']);
}
function requireLogin() {
    if (!isLoggedIn()) {
        header("Location: login.php");
        exit();
    }
}
function logout() {
    session_unset();
    session_destroy();
    header("Location: login.php");
    exit();
}
?>

注册页面

register.php

<?php
require_once 'config/database.php';
require_once 'includes/functions.php';
require_once 'includes/session.php';
$error = '';
$success = '';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $username = validateInput($_POST['username']);
    $email = validateInput($_POST['email']);
    $password = $_POST['password'];
    $confirm_password = $_POST['confirm_password'];
    // 验证
    if (empty($username) || empty($email) || empty($password)) {
        $error = '所有字段都是必填的';
    } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $error = '无效的邮箱格式';
    } elseif (strlen($username) < 3 || strlen($username) > 20) {
        $error = '用户名长度必须在3-20个字符之间';
    } elseif (strlen($password) < 8) {
        $error = '密码长度至少8个字符';
    } elseif ($password !== $confirm_password) {
        $error = '两次密码输入不一致';
    } elseif (checkUsername($username)) {
        $error = '用户名已存在';
    } elseif (checkEmail($email)) {
        $error = '邮箱已被注册';
    } else {
        try {
            $hashedPassword = hashPassword($password);
            $stmt = $pdo->prepare("INSERT INTO users (username, email, password) VALUES (?, ?, ?)");
            $stmt->execute([$username, $email, $hashedPassword]);
            $success = '注册成功!请登录';
        } catch (PDOException $e) {
            $error = '注册失败:' . $e->getMessage();
        }
    }
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">用户注册</title>
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
    <div class="container">
        <div class="form-container">
            <h2>用户注册</h2>
            <?php if ($error): ?>
                <?php echo showError($error); ?>
            <?php endif; ?>
            <?php if ($success): ?>
                <?php echo showSuccess($success); ?>
            <?php endif; ?>
            <form method="POST" action="">
                <div class="form-group">
                    <label for="username">用户名</label>
                    <input type="text" id="username" name="username" 
                           value="<?php echo isset($_POST['username']) ? htmlspecialchars($_POST['username']) : ''; ?>"
                           required minlength="3" maxlength="20">
                </div>
                <div class="form-group">
                    <label for="email">邮箱</label>
                    <input type="email" id="email" name="email" 
                           value="<?php echo isset($_POST['email']) ? htmlspecialchars($_POST['email']) : ''; ?>"
                           required>
                </div>
                <div class="form-group">
                    <label for="password">密码</label>
                    <input type="password" id="password" name="password" required minlength="8">
                    <small>至少8个字符</small>
                </div>
                <div class="form-group">
                    <label for="confirm_password">确认密码</label>
                    <input type="password" id="confirm_password" name="confirm_password" required>
                </div>
                <button type="submit" class="btn btn-primary">注册</button>
            </form>
            <p class="text-center">已有账号?<a href="login.php">立即登录</a></p>
        </div>
    </div>
</body>
</html>

登录页面

login.php

<?php
require_once 'config/database.php';
require_once 'includes/functions.php';
require_once 'includes/session.php';
$error = '';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $username = validateInput($_POST['username']);
    $password = $_POST['password'];
    if (empty($username) || empty($password)) {
        $error = '请输入用户名和密码';
    } else {
        try {
            $stmt = $pdo->prepare("SELECT id, username, email, password, is_active FROM users WHERE username = ? OR email = ?");
            $stmt->execute([$username, $username]);
            $user = $stmt->fetch();
            if ($user && verifyPassword($password, $user['password'])) {
                if ($user['is_active'] == 1) {
                    $_SESSION['user_id'] = $user['id'];
                    $_SESSION['username'] = $user['username'];
                    $_SESSION['email'] = $user['email'];
                    $_SESSION['logged_in'] = true;
                    updateLastLogin($user['id']);
                    header("Location: dashboard.php");
                    exit();
                } else {
                    $error = '账号已被禁用';
                }
            } else {
                $error = '用户名或密码错误';
            }
        } catch (PDOException $e) {
            $error = '登录失败:' . $e->getMessage();
        }
    }
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">用户登录</title>
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
    <div class="container">
        <div class="form-container">
            <h2>用户登录</h2>
            <?php if ($error): ?>
                <?php echo showError($error); ?>
            <?php endif; ?>
            <form method="POST" action="">
                <div class="form-group">
                    <label for="username">用户名或邮箱</label>
                    <input type="text" id="username" name="username" required>
                </div>
                <div class="form-group">
                    <label for="password">密码</label>
                    <input type="password" id="password" name="password" required>
                </div>
                <button type="submit" class="btn btn-primary">登录</button>
            </form>
            <p class="text-center">还没有账号?<a href="register.php">立即注册</a></p>
        </div>
    </div>
</body>
</html>

仪表盘页面(需要登录)

dashboard.php

<?php
require_once 'config/database.php';
require_once 'includes/functions.php';
require_once 'includes/session.php';
requireLogin();
$user = getUserById($_SESSION['user_id']);
if (!$user) {
    logout();
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">用户仪表盘</title>
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
    <div class="container">
        <div class="dashboard">
            <div class="header">
                <h2>欢迎, <?php echo htmlspecialchars($user['username']); ?>!</h2>
                <a href="logout.php" class="btn btn-danger">退出登录</a>
            </div>
            <div class="user-info">
                <h3>用户信息</h3>
                <p><strong>ID:</strong> <?php echo $user['id']; ?></p>
                <p><strong>用户名:</strong> <?php echo htmlspecialchars($user['username']); ?></p>
                <p><strong>邮箱:</strong> <?php echo htmlspecialchars($user['email']); ?></p>
                <p><strong>注册时间:</strong> <?php echo $user['created_at']; ?></p>
                <p><strong>最后登录:</strong> <?php echo $user['last_login'] ? $user['last_login'] : '首次登录'; ?></p>
            </div>
        </div>
    </div>
</body>
</html>

退出登录

logout.php

<?php
require_once 'includes/session.php';
logout();
?>

CSS样式

css/style.css

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
}
.container {
    width: 100%;
    max-width: 600px;
    padding: 20px;
}
.form-container, .dashboard {
    background: white;
    border-radius: 10px;
    box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
    padding: 40px;
}
h2 {
    text-align: center;
    margin-bottom: 30px;
    color: #333;
}
.form-group {
    margin-bottom: 20px;
}
label {
    display: block;
    margin-bottom: 8px;
    color: #555;
    font-weight: 500;
}
input[type="text"],
input[type="email"],
input[type="password"] {
    width: 100%;
    padding: 12px;
    border: 1px solid #ddd;
    border-radius: 5px;
    font-size: 16px;
    transition: border-color 0.3s;
}
input[type="text"]:focus,
input[type="email"]:focus,
input[type="password"]:focus {
    outline: none;
    border-color: #667eea;
}
small {
    display: block;
    color: #888;
    margin-top: 5px;
    font-size: 12px;
}
.btn {
    width: 100%;
    padding: 12px;
    border: none;
    border-radius: 5px;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.3s, transform 0.2s;
}
.btn:hover {
    transform: translateY(-2px);
}
.btn-primary {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
}
.btn-primary:hover {
    background: linear-gradient(135deg, #5a6fd6 0%, #6a3f8a 100%);
}
.btn-danger {
    background: #e74c3c;
    color: white;
    width: auto;
    padding: 10px 20px;
}
.btn-danger:hover {
    background: #c0392b;
}
.alert {
    padding: 12px;
    border-radius: 5px;
    margin-bottom: 20px;
    text-align: center;
}
.alert-error {
    background: #f8d7da;
    color: #721c24;
    border: 1px solid #f5c6cb;
}
.alert-success {
    background: #d4edda;
    color: #155724;
    border: 1px solid #c3e6cb;
}
.text-center {
    text-align: center;
    margin-top: 20px;
}
.text-center a {
    color: #667eea;
    text-decoration: none;
}
.text-center a:hover {
    text-decoration: underline;
}
.dashboard .header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 30px;
    padding-bottom: 20px;
    border-bottom: 2px solid #f0f0f0;
}
.user-info {
    background: #f9f9f9;
    padding: 20px;
    border-radius: 5px;
}
.user-info h3 {
    margin-bottom: 15px;
    color: #333;
}
.user-info p {
    margin-bottom: 10px;
    color: #555;
}
.user-info strong {
    color: #333;
}

首页(可选)

index.php

<?php
require_once 'includes/session.php';
if (isLoggedIn()) {
    header("Location: dashboard.php");
} else {
    header("Location: login.php");
}
exit();
?>

安全性增强建议

  1. 使用HTTPS:始终在线上环境使用HTTPS
  2. CSRF保护:添加CSRF令牌
  3. 限制登录尝试:防止暴力破解
  4. Session安全:设置合理的session配置
  5. 输入验证:前后端都要验证
  6. SQL注入防护:始终使用预处理语句
  7. XSS防护:输出时使用htmlspecialchars

运行测试

  1. 启动Apache和MySQL服务
  2. 导入数据库SQL文件
  3. 将项目文件放在web根目录
  4. 访问:http://localhost/user-system/register.php

这个系统包含了完整的用户注册、登录、会话管理、安全验证等功能,适合初学者学习和实际项目使用。

抱歉,评论功能暂时关闭!