<?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 元
不足点:实际情况中还需要考虑并发的情况,使用队列或者加锁。