simply write that the amount of red packets sent $count should be saved in memcache or redis. Each time the red packets are taken and sent, the values will be added up to no more than the total amount.
example: (the amount of red packets sent is temporarily saved in a static variable and needs to be modified)
function getRedPack($total, $min, $max){
static $count = 0;
$money = mt_rand($min, $max)/100;
$count += $money;
if ($count < $total) {
return $money;
}
return false;
}
can you see if this is all right? that's probably the way of thinking.
/**
*
*
* example
* $coupon = new Coupon(200, 5);
* $res = $coupon->handle();
* print_r($res);
*
* @author Flc <2018-04-06 20:09:53>
* @see http://flc.ren | http://flc.io | https://github.com/flc1125
*/
class Coupon
{
/**
*
*
* @var float
*/
protected $amount;
/**
*
*
* @var int
*/
protected $num;
/**
*
*
* @var float
*/
protected $coupon_min;
/**
*
*
* @var array
*/
protected $items = [];
/**
*
*
* @param float $amount :2
* @param int $num
* @param float $coupon_min
*/
public function __construct($amount, $num = 1, $coupon_min = 0.01)
{
$this->amount = $amount;
$this->num = $num;
$this->coupon_min = $coupon_min;
}
/**
*
*
* @return array
*/
public function handle()
{
// A.
if ($this->amount < $validAmount = $this->coupon_min * $this->num) {
throw new Exception(''.$validAmount.'');
}
// B.
$this->apportion();
return [
'items' => $this->items,
];
}
/**
*
*/
protected function apportion()
{
$num = $this->num; //
$amount = $this->amount; //
while ($num >= 1) {
//
if ($num == 1) {
$coupon_amount = $this->decimal_number($amount);
} else {
$avg_amount = $this->decimal_number($amount / $num); //
$coupon_amount = $this->decimal_number(
$this->calcCouponAmount($avg_amount, $amount, $num)
);
}
$this->items[] = $coupon_amount; //
$amount -= $coupon_amount;
--$num;
}
shuffle($this->items); //
}
/**
*
*
* @param float $avg_amount
* @param float $amount
* @param int $num
*
* @return float
*/
protected function calcCouponAmount($avg_amount, $amount, $num)
{
//
if ($avg_amount <= $this->coupon_min) {
return $this->coupon_min;
}
//
$coupon_amount = $this->decimal_number($avg_amount * (1 + $this->apportionRandRatio()));
//
if ($coupon_amount < $this->coupon_min
|| $coupon_amount > $this->calcCouponAmountMax($amount, $num)
) {
return $this->calcCouponAmount($avg_amount, $amount, $num);
}
return $coupon_amount;
}
/**
* -
*
* @param float $amount
* @param int $num
*/
protected function calcCouponAmountMax($amount, $num)
{
return $this->coupon_min + $amount - $num * $this->coupon_min;
}
/**
*
*/
protected function apportionRandRatio()
{
// 60%
if (rand(1, 100) <= 60) {
return rand(-70, 70) / 100; // 70%
}
return rand(-30, 30) / 100; // 30%;
}
/**
* 2
*
* @param float $amount
*
* @return float
*/
protected function decimal_number($amount)
{
return sprintf('%01.2f', round($amount, 2));
}
}
this code is reproduced to PHPhuo.org users' leaf pit, intruded and deleted!
PHP implements WeChat red packet split algorithm