php签到功能实现
PHP 签到功能实现
数据库设计
创建一个名为sign_in的表,用于存储用户签到记录:

CREATE TABLE `sign_in` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`sign_date` date NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `user_date` (`user_id`,`sign_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
签到功能实现
<?php
// 连接数据库
$db = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
// 获取用户ID(假设已登录)
$user_id = $_SESSION['user_id'];
// 检查今日是否已签到
$stmt = $db->prepare("SELECT COUNT(*) FROM sign_in WHERE user_id = ? AND sign_date = CURDATE()");
$stmt->execute([$user_id]);
$hasSigned = $stmt->fetchColumn();
if ($hasSigned) {
echo "今日已签到";
} else {
// 执行签到
$stmt = $db->prepare("INSERT INTO sign_in (user_id, sign_date) VALUES (?, CURDATE())");
$stmt->execute([$user_id]);
echo "签到成功";
}
?>
连续签到功能
// 检查连续签到天数
$stmt = $db->prepare("
SELECT COUNT(*) as consecutive_days
FROM (
SELECT DISTINCT sign_date
FROM sign_in
WHERE user_id = ?
ORDER BY sign_date DESC
) dates
WHERE DATEDIFF(CURDATE(), sign_date) = (
SELECT COUNT(*) - 1
FROM (
SELECT DISTINCT sign_date
FROM sign_in
WHERE user_id = ?
ORDER BY sign_date DESC
) t
WHERE DATEDIFF(CURDATE(), sign_date) <= (SELECT COUNT(*) - 1 FROM (
SELECT DISTINCT sign_date
FROM sign_in
WHERE user_id = ?
ORDER BY sign_date DESC
) t2)
)
");
$stmt->execute([$user_id, $user_id, $user_id]);
$consecutiveDays = $stmt->fetchColumn();
echo "已连续签到: ".$consecutiveDays."天";
签到奖励系统
// 根据连续签到天数给予奖励
if ($consecutiveDays >= 7) {
// 每周奖励
$reward = 100;
} elseif ($consecutiveDays >= 30) {
// 每月奖励
$reward = 500;
} else {
// 每日基础奖励
$reward = 10;
}
// 更新用户积分
$stmt = $db->prepare("UPDATE users SET points = points + ? WHERE id = ?");
$stmt->execute([$reward, $user_id]);
echo "获得奖励: ".$reward."积分";
签到日历展示
// 获取当月签到记录
$stmt = $db->prepare("
SELECT DAY(sign_date) as day
FROM sign_in
WHERE user_id = ?
AND MONTH(sign_date) = MONTH(CURDATE())
AND YEAR(sign_date) = YEAR(CURDATE())
");
$stmt->execute([$user_id]);
$signedDays = $stmt->fetchAll(PDO::FETCH_COLUMN);
// 生成日历
$daysInMonth = date('t');
$firstDay = date('w', strtotime(date('Y-m-01')));
echo "<table><tr>";
for ($i = 0; $i < $firstDay; $i++) {
echo "<td></td>";
}
for ($day = 1; $day <= $daysInMonth; $day++) {
if (($day + $firstDay - 1) % 7 == 0) {
echo "</tr><tr>";
}
$class = in_array($day, $signedDays) ? 'signed' : '';
echo "<td class='$class'>$day</td>";
}
echo "</tr></table>";
样式示例
.signed {
background-color: #4CAF50;
color: white;
border-radius: 50%;
}
table {
border-collapse: collapse;
}
td {
width: 30px;
height: 30px;
text-align: center;
border: 1px solid #ddd;
}
以上代码实现了一个完整的PHP签到系统,包含基础签到、连续签到计算、奖励系统和日历展示功能。根据实际需求可以进一步扩展和完善。






