php签到逻辑实现
PHP 签到逻辑实现
数据库设计
需要创建用户表和签到记录表,以下为基本字段设计:
用户表 users:

idINT 自增主键usernameVARCHAR 用户名pointsINT 用户积分
签到记录表 sign_records:
idINT 自增主键user_idINT 用户IDsign_dateDATE 签到日期continuous_daysINT 连续签到天数
基础签到功能
// 连接数据库
$pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
// 获取当前用户ID(假设已登录)
$userId = $_SESSION['user_id'];
$currentDate = date('Y-m-d');
// 检查今日是否已签到
$stmt = $pdo->prepare("SELECT * FROM sign_records WHERE user_id = ? AND sign_date = ?");
$stmt->execute([$userId, $currentDate]);
if ($stmt->rowCount() > 0) {
die("今日已签到");
}
// 获取昨日签到记录
$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]);
$lastRecord = $stmt->fetch();
// 计算连续签到天数
$continuousDays = $lastRecord ? $lastRecord['continuous_days'] + 1 : 1;
// 插入签到记录
$stmt = $pdo->prepare("INSERT INTO sign_records (user_id, sign_date, continuous_days) VALUES (?, ?, ?)");
$stmt->execute([$userId, $currentDate, $continuousDays]);
// 更新用户积分
$pointsToAdd = $continuousDays; // 连续签到天数作为积分
$stmt = $pdo->prepare("UPDATE users SET points = points + ? WHERE id = ?");
$stmt->execute([$pointsToAdd, $userId]);
echo "签到成功,连续签到{$continuousDays}天,获得{$pointsToAdd}积分";
连续签到奖励
可以设置阶梯奖励,修改积分计算部分:

// 根据连续天数计算奖励积分
if ($continuousDays >= 7) {
$pointsToAdd = 10; // 连续7天及以上奖励10分
} elseif ($continuousDays >= 3) {
$pointsToAdd = 5; // 连续3-6天奖励5分
} else {
$pointsToAdd = 1; // 1-2天奖励1分
}
补签功能实现
添加补签逻辑,需要检查补签日期是否在允许范围内:
// 补签日期(假设从前端传入)
$makeupDate = $_POST['makeup_date'];
// 检查是否允许补签(例如最多补签7天内)
$maxMakeupDays = 7;
if (strtotime($currentDate) - strtotime($makeupDate) > $maxMakeupDays * 86400) {
die("超过补签期限");
}
// 检查是否已签到
$stmt = $pdo->prepare("SELECT * FROM sign_records WHERE user_id = ? AND sign_date = ?");
$stmt->execute([$userId, $makeupDate]);
if ($stmt->rowCount() > 0) {
die("该日期已签到");
}
// 插入补签记录(连续天数计算需要更复杂逻辑)
$stmt = $pdo->prepare("INSERT INTO sign_records (user_id, sign_date, continuous_days) VALUES (?, ?, ?)");
$stmt->execute([$userId, $makeupDate, 1]); // 简化处理,实际需要重新计算连续天数
// 扣减补签所需积分或消耗补签卡
$stmt = $pdo->prepare("UPDATE users SET points = points - 10 WHERE id = ?");
$stmt->execute([$userId]);
echo "补签成功";
月度签到统计
查询用户当月签到情况:
// 获取当月第一天和最后一天
$firstDay = date('Y-m-01');
$lastDay = date('Y-m-t');
$stmt = $pdo->prepare("SELECT sign_date FROM sign_records
WHERE user_id = ? AND sign_date BETWEEN ? AND ?");
$stmt->execute([$userId, $firstDay, $lastDay]);
$signDates = $stmt->fetchAll(PDO::FETCH_COLUMN);
// 生成日历视图
$calendar = [];
for ($day = 1; $day <= date('t'); $day++) {
$date = date('Y-m-') . str_pad($day, 2, '0', STR_PAD_LEFT);
$calendar[$day] = in_array($date, $signDates);
}
// 输出日历
foreach ($calendar as $day => $signed) {
echo "Day {$day}: " . ($signed ? '✓' : '×') . "\n";
}
安全注意事项
- 所有数据库操作使用预处理语句防止SQL注入
- 重要操作如补签需要验证用户权限
- 签到相关操作建议记录详细日志
- 高并发场景考虑使用事务或锁机制
以上实现可根据实际需求进行调整,如添加签到奖励物品、签到排行榜等功能。






