public function prize_rand($prize_list){ //第一,算出所有的剩余奖品库存 $turntable_total_stock = 0; foreach ($prize_list['prize_list'] as $key => $prize) { $turntable_total_stock += $prize['rest_stock']; } //第二,算出每一类奖品精确的中奖概率:该活动的总中奖率/总库存*该类奖品的库存 //第三,算出每一类奖品实际的中奖概率和总中奖概率:向上取整(精确的中奖概率*基数) foreach ($prize_list['prize_list'] as $key => $prize) { $rest_stock = $prize['rest_stock']; if ($rest_stock > 0) { $probability = $chance * ($rest_stock / $turntable_total_stock) / 100; if ($probability > 0) { $num = $probability * $total;//概率乘以基数,提高精度 $fact_total += ceil($num); $tmp[$key] = ceil($num); } } } //第四,获取一到中奖概率基数之间的随机数(1,100)之间,取到90,大于实际的总中奖概率81,未中奖,否则继续抽奖 $awarded_num = mt_rand(1, $total); if ($awarded_num > $fact_total) { return $result; } //第五,遍历每一类奖品的实际中奖概率,取一到总得实际的中奖概率的随机数(1,81),随机数大于该类奖品的中奖概率,说明未能中该类奖品,总得实际中奖概率-该类奖品的中奖概率,循环到下一类奖品,同上, foreach ($tmp as $k => $proCur) { $randNum = mt_rand(1, $fact_total); if ($randNum <= $proCur) { if ($re['rest_stock'] > 0) { //该奖品有剩余库存 $result = $re; break; } } $fact_total -= $proCur; } return $result; }