php实现按钮签到功能实现
PHP实现按钮签到功能
数据库准备
创建签到表sign_in,包含字段:id(主键)、user_id(用户ID)、sign_date(签到日期)、points(获得积分)。示例SQL:
CREATE TABLE sign_in (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
sign_date DATE NOT NULL,
points INT DEFAULT 10,
UNIQUE KEY (user_id, sign_date)
);
签到逻辑实现 通过判断当天是否已签到防止重复操作:

// 检查是否已签到
function hasSignedToday($userId) {
$today = date('Y-m-d');
$query = "SELECT COUNT(*) FROM sign_in WHERE user_id = ? AND sign_date = ?";
$stmt = $pdo->prepare($query);
$stmt->execute([$userId, $today]);
return $stmt->fetchColumn() > 0;
}
// 执行签到
function doSignIn($userId) {
if (hasSignedToday($userId)) {
return ['status' => 'error', 'message' => '今日已签到'];
}
$today = date('Y-m-d');
$points = 10; // 默认积分
$query = "INSERT INTO sign_in (user_id, sign_date, points) VALUES (?, ?, ?)";
$stmt = $pdo->prepare($query);
$stmt->execute([$userId, $today, $points]);
return ['status' => 'success', 'points' => $points];
}
前端交互 AJAX方式处理签到请求:

$('#signBtn').click(function() {
$.post('sign_in.php', {action: 'sign'}, function(response) {
if (response.status === 'success') {
alert('签到成功,获得' + response.points + '积分');
$('#signBtn').prop('disabled', true);
} else {
alert(response.message);
}
}, 'json');
});
连续签到奖励
扩展签到表增加continuous_days字段,更新签到逻辑:
function checkContinuousSign($userId) {
$yesterday = date('Y-m-d', strtotime('-1 day'));
$query = "SELECT continuous_days FROM sign_in WHERE user_id = ? AND sign_date = ?";
$stmt = $pdo->prepare($query);
$stmt->execute([$userId, $yesterday]);
return $stmt->fetchColumn() ?: 0;
}
function doSignInWithContinuous($userId) {
$continuousDays = checkContinuousSign($userId) + 1;
$points = 10 + floor($continuousDays/7) * 5; // 每周额外奖励
$query = "INSERT INTO sign_in (...) VALUES (..., ?)";
$stmt->execute([..., $continuousDays]);
}
安全防护 添加CSRF防护和频率限制:
session_start();
if (!isset($_POST['token']) || $_POST['token'] !== $_SESSION['token']) {
die('非法请求');
}
// 频率限制
$ip = $_SERVER['REMOTE_ADDR'];
$key = 'sign_limit_' . $ip;
if ($cache->get($key)) {
die('操作过于频繁');
}
$cache->set($key, 1, 60); // 60秒内限制1次






