Appearance
9.6 实操:登录表单、注册表单
本实操将创建完整的登录表单和注册表单,包含表单验证、防XSS攻击等功能。
功能需求
- 注册表单:用户名、邮箱、密码、确认密码
- 登录表单:用户名/邮箱、密码
- 表单验证:非空、格式、长度验证
- 防XSS攻击:使用htmlspecialchars()
- 密码安全:使用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>代码解析
注册表单:
- 包含用户名、邮箱、密码、确认密码字段
- 进行非空、格式、长度验证
- 使用
htmlspecialchars()防止 XSS 攻击 - 使用
password_hash()加密密码 - 模拟用户名和邮箱唯一性检查
登录表单:
- 支持使用用户名或邮箱登录
- 进行非空验证
- 使用
password_verify()验证密码 - 模拟用户查找和验证过程
注意事项
- 数据库连接:实际项目中应该使用真实的数据库连接
- 密码安全:始终使用
password_hash()加密密码,不要明文存储 - 会话管理:登录成功后应该设置会话,跟踪用户登录状态
- 错误处理:提供清晰的错误提示,帮助用户正确填写表单
- 安全性:除了防 XSS 外,还应该考虑 CSRF 防护等安全措施
练习
- 实现真实的数据库连接和用户存储
- 添加会话管理功能
- 实现密码重置功能
- 添加验证码功能,防止暴力破解
