怎样在PHP项目中实现砸金蛋?

wen java案例 2

本文目录导读:

怎样在PHP项目中实现砸金蛋?

  1. 核心实现思路
  2. 完整实现步骤
  3. 进阶优化建议

在PHP项目中实现“砸金蛋”功能,通常涉及前端动画后端逻辑数据库交互三个部分,因为PHP本身是后端语言,主要处理奖品分配、概率控制、用户中奖记录等,而前端负责展示金蛋和砸开的动画效果。

以下是一个完整的实现思路和核心代码示例:

核心实现思路

  1. 概率控制:后端PHP根据预设的中奖概率随机抽取奖品(空奖、谢谢参与、实物奖品、虚拟奖品等)。
  2. 数据存储:记录每个用户的中奖次数、奖品详情到数据库,防止刷奖。
  3. 防作弊:IP限制、用户每日砸蛋次数限制、请求频率限制。
  4. 前端展示:用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>

进阶优化建议

  1. 概率精确控制
    使用抽奖算法(例如基于随机数区间的加权抽取),确保总和为100且可微调。

  2. 防止恶意请求

    • 验证码(砸蛋前需验证)
    • 使用Token防止CSRF
    • 限制同一IP每日请求次数($_SERVER['REMOTE_ADDR']
  3. 奖品发放

    • 虚拟奖品(优惠券、积分)需调用发奖接口。
    • 实物奖品需自动记录并通知运营人员处理。
  4. 前端动画
    可以用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; }
    }
  5. 库存管理
    对于有限数量的实物奖品,需要在数据库中加入库存字段,并发时使用事务+行锁防止超发。


  • PHP负责:抽奖概率计算、每日次数限制、记录日志到数据库、返回JSON结果。
  • 前端负责:展示金蛋样式、处理点击事件、调用AJAX、根据返回结果显示动画和结果文字。
  • 安全考虑:所有逻辑必须在后端完成,前端只是展示,不能相信前端传来的中奖数据。

代码可以直接运行(需配置数据库连接),快速实现一个基础的砸金蛋活动,如果需要更复杂的营销活动(如定时开放、多用户排名等),可以基于这个框架扩展。

抱歉,评论功能暂时关闭!