本文目录导读:

在PHP项目中实现“砸金蛋”功能,通常涉及前端动画、后端逻辑和数据库交互三个部分,因为PHP本身是后端语言,主要处理奖品分配、概率控制、用户中奖记录等,而前端负责展示金蛋和砸开的动画效果。
以下是一个完整的实现思路和核心代码示例:
核心实现思路
- 概率控制:后端PHP根据预设的中奖概率随机抽取奖品(空奖、谢谢参与、实物奖品、虚拟奖品等)。
- 数据存储:记录每个用户的中奖次数、奖品详情到数据库,防止刷奖。
- 防作弊:IP限制、用户每日砸蛋次数限制、请求频率限制。
- 前端展示:用HTML+CSS+JavaScript (jQuery/Vue) 绘制金蛋,点击时发送AJAX请求到后端,根据返回结果显示“碎蛋”动画。
完整实现步骤
数据库设计 (prize_log 表)
CREATE TABLE `prize_log` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) DEFAULT NULL COMMENT '用户ID', `prize_name` varchar(255) DEFAULT NULL COMMENT '奖品名称', `prize_level` tinyint(4) DEFAULT NULL COMMENT '奖品等级:1-特等奖 2-一等奖 3-二等奖 4-三等奖 5-谢谢参与', `create_time` datetime DEFAULT NULL COMMENT '中奖时间', `ip` varchar(50) DEFAULT NULL COMMENT '用户IP', PRIMARY KEY (`id`), KEY `user_id` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
后端PHP API (api.php) - 核心逻辑
<?php
session_start();
header('Content-Type: application/json; charset=utf-8');
// 模拟用户ID(实际从session获取)
$userId = $_SESSION['user_id'] ?? 1;
// --- 每日限制(示例:每天只能砸3次) ---
$today = date('Y-m-d');
$countSql = "SELECT COUNT(*) as cnt FROM prize_log WHERE user_id = ? AND DATE(create_time) = ?";
// 假设已连接数据库 $pdo
$stmt = $pdo->prepare($countSql);
$stmt->execute([$userId, $today]);
$todayCount = $stmt->fetchColumn();
if ($todayCount >= 3) {
echo json_encode(['code' => -1, 'msg' => '今日砸蛋次数已用完', 'prize' => '']);
exit;
}
// --- 奖品池配置(概率总和必须为100) ---
$prizes = [
['level' => 1, 'name' => 'iPhone 15', 'prob' => 1],
['level' => 2, 'name' => '100元话费', 'prob' => 5],
['level' => 3, 'name' => '10元红包', 'prob' => 20],
['level' => 4, 'name' => '优惠券', 'prob' => 34],
['level' => 5, 'name' => '谢谢参与', 'prob' => 40],
];
// --- 按概率抽取奖品 ---
$randNum = mt_rand(1, 100);
$currentProb = 0;
$selectedPrize = null;
foreach ($prizes as $prize) {
$currentProb += $prize['prob'];
if ($randNum <= $currentProb) {
$selectedPrize = $prize;
break;
}
}
// --- 写入中奖记录 ---
$insertSql = "INSERT INTO prize_log(user_id, prize_name, prize_level, create_time, ip) VALUES (?, ?, ?, ?, ?)";
$stmt = $pdo->prepare($insertSql);
$stmt->execute([
$userId,
$selectedPrize['name'],
$selectedPrize['level'],
date('Y-m-d H:i:s'),
$_SERVER['REMOTE_ADDR']
]);
// --- 返回结果(前端用来显示) ---
echo json_encode([
'code' => 0,
'msg' => '恭喜获得' . $selectedPrize['name'],
'prize' => $selectedPrize['name'],
'level' => $selectedPrize['level']
]);
前端HTML+CSS+JS
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">砸金蛋</title>
<style>
.container { text-align: center; margin-top: 50px; }
.eggs { display: flex; justify-content: center; gap: 20px; }
.egg {
width: 100px; height: 120px;
background: radial-gradient(circle at 30% 30%, #ffe5b4, #d4a373);
border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
cursor: pointer;
display: flex; align-items: center; justify-content: center;
font-size: 16px; color: #fff; font-weight: bold;
transition: transform 0.3s;
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
.egg:hover { transform: scale(1.05); }
.egg.smashed {
background: #ccc;
transform: scale(0.8);
opacity: 0.6;
pointer-events: none;
}
.egg.smashed::after {
content: "💥";
font-size: 30px;
}
.result {
margin-top: 20px;
font-size: 20px;
color: #333;
}
</style>
</head>
<body>
<div class="container">
<h1>🎉 砸金蛋赢大奖 🎉</h1>
<div id="eggBox" class="eggs">
<div class="egg" data-id="1">砸我</div>
<div class="egg" data-id="2">砸我</div>
<div class="egg" data-id="3">砸我</div>
</div>
<div id="result" class="result"></div>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(function(){
$('#eggBox').on('click', '.egg:not(.smashed)', function(){
var $egg = $(this);
// 禁用点击
$egg.css('pointer-events', 'none');
// 发送AJAX请求到后端API
$.ajax({
url: 'api.php',
type: 'POST',
data: { egg_id: $egg.data('id'), action: 'smash' },
dataType: 'json',
success: function(res){
if(res.code === 0){
// 显示金蛋破碎效果
$egg.addClass('smashed');
$('#result').html('🥳 ' + res.msg);
} else {
$('#result').html('😥 ' + res.msg);
// 恢复点击
$egg.css('pointer-events', 'auto');
}
},
error: function(){
$('#result').html('网络错误,请稍后重试');
$egg.css('pointer-events', 'auto');
}
});
});
});
</script>
</body>
</html>
进阶优化建议
-
概率精确控制
使用抽奖算法(例如基于随机数区间的加权抽取),确保总和为100且可微调。 -
防止恶意请求
- 加验证码(砸蛋前需验证)
- 使用Token防止CSRF
- 限制同一IP每日请求次数(
$_SERVER['REMOTE_ADDR'])
-
奖品发放
- 虚拟奖品(优惠券、积分)需调用发奖接口。
- 实物奖品需自动记录并通知运营人员处理。
-
前端动画
可以用CSS3动画或Canvas实现更炫酷的破碎效果,.egg.smashed { animation: break 0.5s forwards; } @keyframes break { 0% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.2) rotate(15deg); opacity: 0.7; } 100% { transform: scale(0); opacity: 0; } } -
库存管理
对于有限数量的实物奖品,需要在数据库中加入库存字段,并发时使用事务+行锁防止超发。
- PHP负责:抽奖概率计算、每日次数限制、记录日志到数据库、返回JSON结果。
- 前端负责:展示金蛋样式、处理点击事件、调用AJAX、根据返回结果显示动画和结果文字。
- 安全考虑:所有逻辑必须在后端完成,前端只是展示,不能相信前端传来的中奖数据。
代码可以直接运行(需配置数据库连接),快速实现一个基础的砸金蛋活动,如果需要更复杂的营销活动(如定时开放、多用户排名等),可以基于这个框架扩展。