zoukankan      html  css  js  c++  java
  • PHP版滑动时间窗口算法

    <?php
    session_start();
    $time = 60;//60秒
    $count = 10; //可访问 10次
    
    //第一次初始化
    if(!isset($_SESSION['count'])){
    
        $_SESSION['count'] = 1;
        $_SESSION['time'] = time();
        $_SESSION['cha'] = 0;
        $_SESSION['status'] = 'success';
        print_r($_SESSION);
    
    }else {
    
    
        $now = time();
        $cha = $now - $_SESSION['time'];
        $avg = intval($time / $count);//平均多少秒可获得一次机会
    
        //如果超过次数
        if($_SESSION['count'] > $count){
    
            //如果时差超过平均可获得次数的时长
            if($cha > $avg){
    
                $_SESSION['count'] -= intval($cha / $avg); //计算可得多少次机会
                $_SESSION['count'] = max($_SESSION['count'], 0);//修正次数不能为负。
    
                $_SESSION['count']++;
                $_SESSION['time'] = $now;
                $_SESSION['cha'] = $cha;
                $_SESSION['status'] = 'success';
                print_r($_SESSION);
    
            }else{
    
                //如果时差没有超过 $avg ,则还是失败。
                $_SESSION['cha'] = $cha;
                $_SESSION['status'] = 'fail';
                print_r($_SESSION);
    
            }
    
    
        }else{
            //如果没超过次数正常访问
    
            if($cha > $avg) {
                $_SESSION['count'] -= intval($cha / $avg); //计算可得多少次机会
                $_SESSION['count'] = max($_SESSION['count'], 0);//修正次数不能为负。
            }
    
            $_SESSION['count']++;
            $_SESSION['time'] = $now;
            $_SESSION['cha'] = $cha;
            $_SESSION['status'] = 'success';
            print_r($_SESSION);
    
        }
    
    
    }

    如果要精确计算,则要记录每次访问以元素的形式记录时间戳,到数组,每次请求的时候,遍历数组元素中的时间戳,与当前时间比较,清理掉 N分钟之前的元素,然后再计算个数,如果个数没超,则允许,反之不行。

    /**
     * 滑动时间窗口
     * 每次成功访问时,记录访问时间点
     * 每次清理N分钟之前的访问时间点
     * 对访问次数进行计数,判断是否超过次数
     * @param $minute
     * @param $count
     * @param $times
     * @return bool
     */
    function timeWindow($minute, $count, &$times){
    
        $now = time();
        $point = $now - $minute * 60;//从当前时间往前推N分钟的时间点
        foreach($times as $key => $item){
            if($item < $point) unset($times[$key]); //把N分钟之前的访问清理掉
        }
    
        if(count($times) <= $count){
            $times[] = $now; //成功时,记录本次访问时间点
            return true;
        }
        return false;
    
    }
  • 相关阅读:
    px和rem换算
    使用Android Studio创建Android项目
    Hopscotch
    AtCoder Grand Contest 010 --C:Cleaning
    Hello world!
    概率生成函数
    FFT 学习笔记
    扩展中国剩余定理(excrt)
    组合恒等式
    常见数列
  • 原文地址:https://www.cnblogs.com/zbseoag/p/14284377.html
Copyright © 2011-2022 走看看