PHP 实现简单的抽奖系统

本文介绍了如何使用PHP结合MySQL数据库实现一个简单的抽奖系统。系统包括了物品表和用户已获得商品表的设计,以及如何根据概率计算中奖商品和记录用户获奖信息的逻辑。

抽奖是很多活动中常见的一种方式,它可以吸引用户参与,并且带来一定的趣味性。在 PHP 中实现抽奖功能并不难,本文将介绍如何使用 PHP 实现简单的抽奖系统。

抽奖系统设计

一个简单的抽奖系统需要具备以下基本功能:

  1. 展示可供用户抽取的物品列表;
  2. 记录每个物品被中了多少次;
  3. 记录每个用户获得了哪些物品。

因此,我们需要设计两张表:一个是用于记录可供用户选择的物品列表和对应中奖概率;另一个则是用于记录每个用户获得了哪些商品。这里我们假设有三种商品 A、B、C 可以被选中,它们对应的中奖概率分别为 10%、20% 和 70%。

物品表(prize)

字段名类型描述
idint(11) unsigned主键
namevarchar(255)商品名称
probabilitydecimal(10,2) unsigned not null default ‘0’ comment ‘中奖概率(百分比)’

用户已获得商品表(user_prize)

字段名类型描述
idint(11) unsigned主键
user_idint(11) unsigned not null comment ‘用户ID’
prize_idint(11) unsigned not null comment ‘商品ID’
create_timedatetime not null default current_timestamp comment ‘创建时间’

抽奖系统实现

在开始实现之前,我们需要先将上述表结构在数据库中创建好。这里我们使用 MySQL 数据库,通过执行以下 SQL 语句来创建两张表:

CREATE TABLE `prize` (
    `id` int(10) UNSIGNED NOT NULL,
    `name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '商品名称',
    `probability` decimal(10,2) UNSIGNED NOT NULL DEFAULT '0.00' COMMENT '中奖概率(百分比)',
    PRIMARY KEY (`id`)
);

CREATE TABLE `user_prize` (
    `id` int(10) UNSIGNED NOT NULL,
    `user_id` int(11) UNSIGNED NOT NULL COMMENT '用户ID',
    `prize_id` int(11) UNSIGNED NOT NULL COMMENT '商品ID',
     create_time datetime not null default current_timestamp on update current_timestamp comment "创建时间",
     PRIMARY KEY (`id`),
     key(`user_id`),
     key(`prize_id`)
);

展示可供用户抽取的物品列表

首先,我们需要从物品表(prize)中查询出所有可供抽取的物品,并按照率大小排序展示给用户。

// 查询出所有可供抽取的物品并按照概率排序
$sql = 'SELECT * FROM `prize` ORDER BY `probability` DESC';
$stmt = $pdo->prepare($sql);
$stmt->execute();
$prizes = $stmt->fetchAll(PDO::FETCH_ASSOC);

// 展示可供抽取的物品列表
foreach ($prizes as $prize) {
    echo '<div>';
    echo '<span>' . $prize['name'] . '</span>';
    echo '<button data-prize-id="' . $prize['id'] . '">抽奖</button>';
    echo '</div>';
}

上面代码中,我们首先使用 SQL 查询语句从数据库中查询出所有可供抽取的物品,并按照概率大小排序。然后在前端展示每个商品名称和对应的“抽奖”按钮。

抽奖

接下来,我们需要编写一个 PHP 接口来处理用户点击“抽奖”按钮时发生的事件。在该接口中,我们需要完成以下任务:

  1. 根据随机数和各个商品对应的中奖概率计算出用户实际获得了哪种商品;
  2. 记录用户已经获得了哪些商品。
<?php

// 处理用户点击“抽奖”按钮时发生的事件
if (isset($_POST['action']) && $_POST['action'] === 'draw') {
    // 随机生成一个 0-100 的整数作为判断结果依据
    $randNum = mt_rand(0, 100);

    // 查询出所有可供抽取的物品并按照概率排序
    $sql = 'SELECT * FROM `prize` ORDER BY `probability` DESC';
    $stmt = $pdo->prepare($sql);
    $stmt->execute();
    $prizes = $stmt->fetchAll(PDO::FETCH_ASSOC);

    // 根据随机数和各个商品对应的中奖概率计算出用户实际获得了哪种商品
    foreach ($prizes as $prize) {
        if ($randNum < intval($prize['probability'] * 100)) {
            // 记录用户已经获得了哪些商品
            recordUserPrize($_SESSION['user_id'], intval($prize['id']));
            echo json_encode([
                'status' => 'success',
                'data' => [
                    'name' => $prize['name']
                ]
            ]);
            exit;
        }
        else {
            // 如果该物品未被抽中,则将其概率减去当前已经抽中的所有物品的概率之和,以保证下一个物品有更高的中奖几率。
            continue;
        }
    }

    echo json_encode([
        'status' => 'error',
        'message' => "没有可供抽取的物品。"
   ]);
}

function recordUserPrize($userId, $prizeId)
{
   global $pdo;

   try {
       // 向 user_prize 表插入一条新记录,表示用户获得了某个奖项。
       $sql = "INSERT INTO `user_prize` (`user_id`, `prize_id`) VALUES (:userId, :prizeId)";
       $stmt = pdo()->prepare($sql);
       $stmt->bindValue(':userId', $userId, PDO::PARAM_INT);
       $stmt->bindValue(':prizeId', $prizeId, PDO::PARAM_INT);
       $stmt->execute();
   }
   catch (\Exception $e) {
       // 记录日志或者抛出异常等处理...
   }
}

上面代码中,我们首先随机生成一个 0-100 的整数作为判断结果依据。然后查询出所有可供抽取的物品并按照概率排序,并在循环中根据随机数和各个商品对应的中奖概率计算出用户实际获得了哪种商品。如果该物品未被抽中,则将其概率减去当前已经抽中的所有物品的概率之和,以保证下一个物品有更高的中奖几率。

最后,我们向 user_prize 表插入一条新记录,表示用户获得了某个奖项。

总结

本文介绍了如何使用 PHP 实现简单的抽奖系统。通过本文所提供的代码示例,读者可以清晰地看到每一步操作都是如何完成的,并且能够根据自己需求进行扩展和优化。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值