本文目录导读:

我来详细说明如何从零开始用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();
?>
安全性增强建议
- 使用HTTPS:始终在线上环境使用HTTPS
- CSRF保护:添加CSRF令牌
- 限制登录尝试:防止暴力破解
- Session安全:设置合理的session配置
- 输入验证:前后端都要验证
- SQL注入防护:始终使用预处理语句
- XSS防护:输出时使用htmlspecialchars
运行测试
- 启动Apache和MySQL服务
- 导入数据库SQL文件
- 将项目文件放在web根目录
- 访问:http://localhost/user-system/register.php
这个系统包含了完整的用户注册、登录、会话管理、安全验证等功能,适合初学者学习和实际项目使用。