)
注意: probability(概率)之和必须100下面方法为简单没有库存public function draw() { $draw_list [ [ name 空奖(0-80), probability 80.00 ], [ name 5积分(80-90), probability 10.00 ], [ name 10积分(90-98), probability 8.00 ], [ name 20积分(98-100), probability 2.00 ], ]; // 生成一个0到100之间的随机数 $randomNum random_int(0, 100); $currentProbability 0; foreach ($draw_list as $draw_info) { $currentProbability $draw_info[probability]; if ($randomNum $currentProbability) { $draw_info[currentProbability] $currentProbability; $draw_info[randomNum] $randomNum; $draw_result $draw_info; break; } } $this-success(请求成功!, $draw_result); }含有库存写法public function draw_test() { $draw_list [ [ name 空奖(0-80), probability 80.00, stock 0 ], [ name 5积分(80-90), probability 10.00, stock 1 ], [ name 10积分(90-98), probability 9.9999999, stock 0 ], [ name 20积分(98-100), probability 0.0000001, stock 1 ], ]; // 修改这里调整支持的小数位数 $scale 100000000; // 整数溢出安全校验 $maxExpectTotalWeight 100 * $scale; // 预留1/2安全余量防止后续分摊权重后溢出 if ($maxExpectTotalWeight PHP_INT_MAX / 2) { $this-error(scale配置过大存在整数溢出风险请调小scale值); } $emptyTotalWeight 0; $validList []; foreach ($draw_list as $item) { $p (float)$item[probability]; $intWeight (int)round($p * $scale); if ($item[stock] 0) { $validList[] [ name $item[name], probability $item[probability], //保留原始概率 weight $intWeight, stock $item[stock] ]; } else { $emptyTotalWeight $intWeight; } } // 边界全部奖品库存为0 if (empty($validList)) { $this-error(暂无可用奖品); } // 将库存0的奖项权重分摊到有效奖品 if ($emptyTotalWeight 0) { $validCount count($validList); $avgAdd (int)($emptyTotalWeight / $validCount); $remainder $emptyTotalWeight % $validCount; //余数补到最后一项 foreach ($validList as $idx $v) { $v[weight] $avgAdd; if ($idx $validCount - 1) { $v[weight] $remainder; } } unset($v); } $totalWeight array_sum(array_column($validList, weight)); // 极端保护总权重不能小于1 if ($totalWeight 1) { $this-error(奖品权重合计异常); } $rand mt_rand(1, $totalWeight); $currentWeight 0; $draw_result null; foreach ($validList as $row) { $currentWeight $row[weight]; if ($rand $currentWeight) { $draw_result $row; $draw_result[rand] $rand; $draw_result[totalWeight] $totalWeight; break; } } $this-success(请求成功!, $draw_result); }