可以自定义红包总金额,总包数,每包最小金额
<?php
/**
* 红包类
*/
class RedPacket
{
// 要发的红包总金额
private $total = 0.01;
// 总共要发红包总包数
private $bags = 1;
// 每包最小红包金额数
private $min = 0.01;
function __construct($total, $bags, $min){
$this->total = $total;
$this->bags = $bags;
$this->min = $min;
}
/**
* [发红包]
* @return [array] [红包的每包金额数组]
*/
public function give_red_packets()
{
$redpacket_arr = [];
//根据最小值不一样,需要转化
switch (true) {
case $this->min >= 1:
$right_value = 1;
break;
case $this->min >= 0.1:
$right_value = 10;
break;
case $this->min >= 0.01:
$right_value = 100;
break;
}
for($i = 1;$i < $this->bags;$i++){//设置循环,边界值是红包数-1
//保证后面至少有($bags - $i)个最小金额可以发,通过公式模拟数学中的离散模型
$safe = bcdiv(($this->total - ($this->bags - $i) * $this->min), ($this->bags - $i), 2);
//根据离散数学模型得到每个红包的金额
$rand = rand(0, bcmul($safe - $this->min, $right_value, 2)) + $this->min;
//如果大于倍值,需要转化,反之,不需要。为了防止有的红包金额小于设定的最小金额
if ($rand >= ($this->min * $right_value)) {
$money = bcdiv($rand, $right_value, 2);
} else {
$money = strval($rand);
}
$this->total -= $money; //替换$total的值
$redpacket_arr[] = number_format($money, 2);//把每个红包金额数格式化,存起来
}
$left = number_format($this->total, 2);//调用number_format()方法,对数字$total格式化
$redpacket_arr[] = $left;//输出最后一个红包
return $redpacket_arr;
}
}
//发红包
$redpacket = new RedPacket(881.88, 20, 1.5);
$redpacket_arr = $redpacket->give_red_packets();
echo '<pre>';
print_r($redpacket_arr);
print_r('红包总金额:' . array_sum($redpacket_arr));
echo '</pre>';
881.88元,20包,每包至少1.5元
效果截图:
100元,33包,每包至少0.01元