<?php
/* * 生成紅包的函數 */
function getRandMoney($totalMoney, $totalPeople = 2, $miniMoney = 1)
{
$randRemainMoney = $totalMoney - $totalPeople * $miniMoney; //剩餘需要隨機的錢數
return _getRandMoney($randRemainMoney, $totalPeople, $miniMoney);
}
/* * 紅包生成的邏輯代碼 */
function _getRandMoney($totalMoney, $totalPeople, $miniMoney)
{
$returnMessage = array('status' => 1, 'data' => NULL);
if ($totalMoney > 0) {
$returnMessage['data'] = _randMoney($totalMoney, $totalPeople, $miniMoney);
} elseif ($totalMoney == 0) {
$returnMessage['data'] = array_fill(0, $totalPeople, 1);
} else {
$returnMessage['status'] = -1;
$returnMessage['data'] = '參數傳遞有誤,生成紅包失敗';
}
return $returnMessage;
}
/* 參數無誤,開始生成對應的紅包金額 */
function _randMoney($totalMoney, $totalPeople, $miniMoney)
{
$data = array_fill(0, $totalPeople, $miniMoney);
if ($totalPeople > 1) {
foreach ($data as $k => $v) {
if ($k == $totalPeople - 1) {
$data[$k] = $totalMoney + $v;
break;
} else {
if ($totalMoney == 0)
break;
$randMoney = rand(0, $totalMoney);
$totalMoney -= $randMoney;
$data[$k] = $randMoney + $v;
}
}
}
return $data;
}
class redpack
{
//總金額
private $total = 0;
//紅包數量
private $num = 0;
//最小紅包金額
private $min = 0.01;
public function __construct($total, $num, $min)
{
$this->total = $total;
$this->num = $num;
$this->min = $min;
}
//紅包結果
public function getPack()
{
$total = $this->total;
$num = $this->num;
$min = $this->min;
for ($i = 1; $i < $num; $i++) {
$safe_total = ($total - ($num - $i) * $min) / ($num - $i); //隨機安全上限
$money = mt_rand($min * 100, $safe_total * 100) / 100;
$total = $total - $money;
//紅包數據
$readPack[] = [
'money' => $money,
'balance' => $total,
];
}
//最後一個紅包,不用隨機
$readPack[] = [
'money' => $money,
'balance' => 0,
];
//返回結果
return $readPack;
}
}
$money = getRandMoney(20, 10, 0.01);
var_dump($money);
$total = 20; //紅包總金額
$num = 10; // 分成10個紅包,支持10人隨機領取
$min = 0.01; //每個人最少能收到0.01元
$redpack = new redpack($total, $num, $min);
$jieguo = $redpack->getPack();
foreach ($jieguo as $key => $val) {
$n = $key + 1;
echo '第' . $n . '個紅包:' . $val['money'] . ' 元,餘額:' . $val['balance'] . ' 元<br>';
}
輸出結果:
array (size=2)
'status' => int 1
'data' =>
array (size=10)
0 => float 5.01
1 => float 6.01
2 => float 1.01
3 => float 5.01
4 => float 1.01
5 => float 1.01
6 => float 0.01
7 => float 0.01
8 => float 0.01
9 => float 0.91
第1個紅包:0.6 元,餘額:19.4 元
第2個紅包:1.23 元,餘額:18.17 元
第3個紅包:0.47 元,餘額:17.7 元
第4個紅包:1.12 元,餘額:16.58 元
第5個紅包:0.37 元,餘額:16.21 元
第6個紅包:3.4 元,餘額:12.81 元
第7個紅包:4.02 元,餘額:8.79 元
第8個紅包:3.85 元,餘額:4.94 元
第9個紅包:0.96 元,餘額:3.98 元
第10個紅包:0.96 元,餘額:0 元
不足點:實際情況中還需要考慮併發的情況,使用隊列或者加鎖。