php 实现 签到功能实现
数据库设计
创建一张签到记录表,包含用户ID、签到日期和连续签到天数等字段。表结构如下:
CREATE TABLE `sign_records` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`sign_date` date NOT NULL,
`continuous_days` int(11) NOT NULL DEFAULT 1,
PRIMARY KEY (`id`),
UNIQUE KEY `user_date` (`user_id`,`sign_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
签到逻辑实现
检查用户当天是否已签到,未签到则插入记录并更新连续签到天数。使用事务确保数据一致性:
function signIn($userId) {
$today = date('Y-m-d');
$pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
try {
$pdo->beginTransaction();
// 检查是否已签到
$stmt = $pdo->prepare("SELECT 1 FROM sign_records WHERE user_id = ? AND sign_date = ?");
$stmt->execute([$userId, $today]);
if ($stmt->fetch()) {
throw new Exception('今日已签到');
}
// 获取昨天签到记录
$yesterday = date('Y-m-d', strtotime('-1 day'));
$stmt = $pdo->prepare("SELECT continuous_days FROM sign_records WHERE user_id = ? AND sign_date = ?");
$stmt->execute([$userId, $yesterday]);
$continuousDays = $stmt->fetch() ? $stmt->fetchColumn() + 1 : 1;
// 插入签到记录
$stmt = $pdo->prepare("INSERT INTO sign_records (user_id, sign_date, continuous_days) VALUES (?, ?, ?)");
$stmt->execute([$userId, $today, $continuousDays]);
$pdo->commit();
return ['success' => true, 'continuous_days' => $continuousDays];
} catch (Exception $e) {
$pdo->rollBack();
return ['success' => false, 'message' => $e->getMessage()];
}
}
签到奖励处理
根据连续签到天数发放不同奖励,可在签到成功后调用奖励发放逻辑:
function giveSignReward($userId, $continuousDays) {
$rewards = [
3 => ['points' => 10],
7 => ['points' => 30, 'vip_days' => 1],
30 => ['points' => 100, 'vip_days' => 7]
];
if (isset($rewards[$continuousDays])) {
// 实现奖励发放逻辑
// 如更新用户积分、VIP有效期等
return $rewards[$continuousDays];
}
return null;
}
前端接口设计
提供签到状态查询和签到操作两个接口:
// 获取签到状态
$app->get('/sign/status/{user_id}', function ($request, $response, $args) {
$userId = $args['user_id'];
$today = date('Y-m-d');
$stmt = $pdo->prepare("SELECT 1 FROM sign_records WHERE user_id = ? AND sign_date = ?");
$stmt->execute([$userId, $today]);
$signed = (bool)$stmt->fetch();
return $response->withJson(['signed' => $signed]);
});
// 执行签到
$app->post('/sign/{user_id}', function ($request, $response, $args) {
$result = signIn($args['user_id']);
if ($result['success']) {
$reward = giveSignReward($args['user_id'], $result['continuous_days']);
$result['reward'] = $reward;
}
return $response->withJson($result);
});
数据统计功能
添加按月统计签到次数的功能,便于后台管理:
function getMonthlySignData($userId, $yearMonth) {
$startDate = "$yearMonth-01";
$endDate = date('Y-m-t', strtotime($startDate));
$stmt = $pdo->prepare("
SELECT sign_date, continuous_days
FROM sign_records
WHERE user_id = ? AND sign_date BETWEEN ? AND ?
ORDER BY sign_date
");
$stmt->execute([$userId, $startDate, $endDate]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}






