本文目录导读:

我来为你详细介绍PHP注册邀请码机制的实现方案。
数据库设计
邀请码表
CREATE TABLE `invite_codes` ( `id` int(11) NOT NULL AUTO_INCREMENT, `code` varchar(20) NOT NULL COMMENT '邀请码', `user_id` int(11) DEFAULT NULL COMMENT '生成邀请码的用户ID', `status` tinyint(1) DEFAULT '0' COMMENT '状态:0未使用,1已使用,2已过期', `used_by` int(11) DEFAULT NULL COMMENT '使用该邀请码的用户ID', `used_at` datetime DEFAULT NULL COMMENT '使用时间', `expire_at` datetime DEFAULT NULL COMMENT '过期时间', `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uk_code` (`code`), KEY `idx_user_id` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
用户表设计
CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL, `password` varchar(255) NOT NULL, `email` varchar(100) DEFAULT NULL, `invited_by` int(11) DEFAULT NULL COMMENT '邀请人用户ID', `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uk_username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
核心PHP代码实现
邀请码生成类
<?php
class InviteCode {
private $db;
public function __construct($db) {
$this->db = $db;
}
/**
* 生成邀请码
* @param int $userId 用户ID
* @param int $count 生成数量
* @param int $expireDays 过期天数
* @return array 生成的邀请码
*/
public function generate($userId, $count = 1, $expireDays = 30) {
$codes = [];
$expireAt = date('Y-m-d H:i:s', strtotime("+{$expireDays} days"));
for ($i = 0; $i < $count; $i++) {
$code = $this->generateUniqueCode();
$sql = "INSERT INTO invite_codes (code, user_id, expire_at) VALUES (?, ?, ?)";
$stmt = $this->db->prepare($sql);
$stmt->bind_param("sis", $code, $userId, $expireAt);
if ($stmt->execute()) {
$codes[] = $code;
}
}
return $codes;
}
/**
* 生成唯一邀请码
*/
private function generateUniqueCode() {
$characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$code = '';
$max = strlen($characters) - 1;
do {
$code = '';
for ($i = 0; $i < 8; $i++) {
$code .= $characters[random_int(0, $max)];
}
} while ($this->codeExists($code));
return $code;
}
/**
* 检查邀请码是否已存在
*/
private function codeExists($code) {
$sql = "SELECT id FROM invite_codes WHERE code = ?";
$stmt = $this->db->prepare($sql);
$stmt->bind_param("s", $code);
$stmt->execute();
$result = $stmt->get_result();
return $result->num_rows > 0;
}
/**
* 验证邀请码
*/
public function validate($code) {
$sql = "SELECT * FROM invite_codes WHERE code = ? AND status = 0";
$stmt = $this->db->prepare($sql);
$stmt->bind_param("s", $code);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows === 0) {
return ['valid' => false, 'message' => '邀请码不存在或已被使用'];
}
$inviteCode = $result->fetch_assoc();
// 检查过期
if (strtotime($inviteCode['expire_at']) < time()) {
return ['valid' => false, 'message' => '邀请码已过期'];
}
return ['valid' => true, 'data' => $inviteCode];
}
/**
* 使用邀请码
*/
public function useCode($code, $userId) {
$sql = "UPDATE invite_codes
SET status = 1, used_by = ?, used_at = NOW()
WHERE code = ? AND status = 0";
$stmt = $this->db->prepare($sql);
$stmt->bind_param("is", $userId, $code);
return $stmt->execute();
}
/**
* 获取用户的邀请记录
*/
public function getInviteRecords($userId) {
$sql = "SELECT u.username, u.created_at
FROM users u
WHERE u.invited_by = ?";
$stmt = $this->db->prepare($sql);
$stmt->bind_param("i", $userId);
$stmt->execute();
return $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
}
}
注册处理逻辑
<?php
class Register {
private $db;
private $inviteCode;
public function __construct($db) {
$this->db = $db;
$this->inviteCode = new InviteCode($db);
}
/**
* 注册新用户
*/
public function register($username, $password, $invite_code = '') {
// 1. 验证输入
if (empty($username) || empty($password)) {
return ['success' => false, 'message' => '用户名和密码不能为空'];
}
// 2. 检查用户名是否已存在
if ($this->usernameExists($username)) {
return ['success' => false, 'message' => '用户名已存在'];
}
// 3. 验证邀请码(如果开启强制邀请)
if (!empty($invite_code)) {
$inviteValidation = $this->inviteCode->validate($invite_code);
if (!$inviteValidation['valid']) {
return ['success' => false, 'message' => $inviteValidation['message']];
}
} elseif ($this->requireInviteCode()) {
return ['success' => false, 'message' => '请填写邀请码'];
}
// 4. 创建用户
$invitedBy = null;
if (!empty($invite_code) && $inviteValidation['valid']) {
$invitedBy = $inviteValidation['data']['user_id'];
}
$passwordHash = password_hash($password, PASSWORD_BCRYPT);
$sql = "INSERT INTO users (username, password, invited_by) VALUES (?, ?, ?)";
$stmt = $this->db->prepare($sql);
$stmt->bind_param("ssi", $username, $passwordHash, $invitedBy);
if ($stmt->execute()) {
$userId = $stmt->insert_id;
// 5. 标记邀请码为已使用
if (!empty($invite_code)) {
$this->inviteCode->useCode($invite_code, $userId);
}
return ['success' => true, 'message' => '注册成功', 'user_id' => $userId];
}
return ['success' => false, 'message' => '注册失败'];
}
private function usernameExists($username) {
$sql = "SELECT id FROM users WHERE username = ?";
$stmt = $this->db->prepare($sql);
$stmt->bind_param("s", $username);
$stmt->execute();
return $stmt->get_result()->num_rows > 0;
}
private function requireInviteCode() {
// 这里可以配置是否需要强制邀请码
return true;
}
}
控制器/接口示例
<?php
// 处理注册请求
class RegisterController {
public function handleRegister() {
// 模拟数据库连接
$db = new mysqli('localhost', 'user', 'password', 'database');
$register = new Register($db);
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
$inviteCode = $_POST['invite_code'] ?? '';
$result = $register->register($username, $password, $inviteCode);
header('Content-Type: application/json');
echo json_encode($result);
}
// 生成邀请码接口(仅限已登录用户)
public function generateInviteCodes() {
session_start();
if (!isset($_SESSION['user_id'])) {
echo json_encode(['success' => false, 'message' => '请先登录']);
return;
}
$db = new mysqli('localhost', 'user', 'password', 'database');
$inviteCode = new InviteCode($db);
$count = $_POST['count'] ?? 1;
$expireDays = $_POST['expire_days'] ?? 30;
$codes = $inviteCode->generate($_SESSION['user_id'], $count, $expireDays);
echo json_encode(['success' => true, 'codes' => $codes]);
}
}
用户体验优化
前端表单示例
<!DOCTYPE html>
<html>
<head>注册</title>
</head>
<body>
<form id="registerForm">
<input type="text" name="username" placeholder="用户名" required>
<input type="password" name="password" placeholder="密码" required>
<input type="text" name="invite_code" placeholder="邀请码(必填)" required>
<button type="submit">注册</button>
</form>
<script>
document.getElementById('registerForm').addEventListener('submit', function(e) {
e.preventDefault();
// 使用ajax提交数据
});
</script>
</body>
</html>
邀请码状态检查
// 检查邀请码状态(AJAX接口)
public function checkInviteCode() {
$code = $_GET['code'] ?? '';
$inviteCode = new InviteCode($db);
$result = $inviteCode->validate($code);
if ($result['valid']) {
echo json_encode(['valid' => true, 'message' => '邀请码有效']);
} else {
echo json_encode(['valid' => false, 'message' => $result['message']]);
}
}
安全考虑与最佳实践
- 防并发问题:使用事务处理邀请码的使用
- 数据验证:严格验证所有输入
- SQL注入防护:使用预处理语句
- 邀请码长度:建议使用8-10位,包含字母和数字
- 过期策略:设置合理的过期时间
- 使用次数限制:限制单个用户可生成的邀请码数量
- 日志记录:记录所有邀请码的生成和使用记录
- 定期清理:定期清理过期的邀请码
这就是一个完整的PHP注册邀请码机制实现,可以根据实际需求进行调整和扩展。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播