• php生成随机拼手气红包与固定金额红包

    2018-10-26 18:17:43

    发红包已经成了中国人的习惯,发微信红包不仅是我们日常的基本操作,更是是节假日、喜庆时分亲朋好友同事之间祝福必不可少的环节。

    参考网上代码与思路,整理了一份利用php生成拼手气与固定金额红包的代码,当然拼手气的随机性符不符合正态分布并没有做验证。实际项目中,可以将生成的红包数组存入数据库,这样就是一个红包了。

    <?php
    /**
     * 拼手气红包实现
     * 生成num个随机数,每个随机数占随机数总和的比例*money_total的值即为每个红包的钱额
     * 考虑到精度问题,最后重置最大的那个红包的钱额为money_total-其他红包的总额
     * 浮点数比较大小,使用number_format,精确到2位小数
     *
     * @param double $money_total  总钱额, 每人最少0.01,精确到2位小数
     * @param int $num 发送给几个人
     * @return array num个元素的一维数组,值是随机钱额
     */
    function random_red_envelope($money_total, $num) {
        if($money_total < 0.1) {
            return "红包总额不能小于0.1元";
        }
        if($money_total > 200) {
            return "红包总额不能大于200元";
        }
        if(1 > $num) {
            return "红包数不能少于1";
        }
        if($money_total < $num*0.01) {
            return "钱不够分";
        }
    
        $rand_arr = [];
        for($i=0; $i<$num; $i++) {
            $rand_arr[] = rand(1, 100);
        }
    
        $rand_sum = array_sum($rand_arr);
        $rand_money_arr = array();
        $rand_money_arr = array_pad($rand_money_arr, $num, 0.01);  //保证每个红包至少0.01
    
        foreach ($rand_arr as $key => $r) {
            $rand_money = number_format($money_total*$r/$rand_sum, 2);
    
            if($rand_money <= 0.01 || number_format(array_sum($rand_money_arr), 2) >= number_format($money_total, 2)) {
                $rand_money_arr[$key] = 0.01;
            } else {
                $rand_money_arr[$key] = $rand_money;
            }
    
        }
    
        $max_index = $max_rand = 0;
        foreach ($rand_money_arr as $key => $rm) {
            if($rm > $max_rand) {
                $max_rand = $rm;
                $max_index = $key;
            }
        }
    
        unset($rand_money_arr[$max_index]);
        //这里的array_sum($rand_money_arr)一定是小于$money_total的
        $rand_money_arr[$max_index] = number_format($money_total - array_sum($rand_money_arr), 2);
    
        shuffle($rand_money_arr);
        return $rand_money_arr;
    }
    
    /**
     * 等额红包
     * @param double $num 每个金额
    * @param int $count 均分个数 * @return array $arr 红包数组 */ function equal_red_envelope($num, $count){ $sum = $num * $count; if($num < 0.01 || $sum < 0.1){ return '单个红包不能小于0.01元,红包总额不能小于0.1元'; } $arr = []; for($i=0 ; $i<$count ; $i++){ $arr[$i] = $num; } return $arr; } $result = random_red_envelope(100, 10); print_r($result); echo '<br>'; $result = equal_red_envelope(1,10); print_r($result);