检查/设置用户访问频率

jerry thinkphp 2015年11月19日 收藏
检查/设置用户访问频率 指定 user_marked在 time_slot 秒内最多访问 count次;
/**
 * 检查/设置用户访问频率 指定 user_marked在 time_slot 秒内最多访问 count次;
 * @param $lime_slot 时间片 单位秒
 * @param $count 整数
 * @param $user_marked 用户唯一标示,默认为客户端IP
 * @return array('status'=>1,'info'=>'') 
 * @author leeyi <leeyisoft@qq.com>
 */
function check_rate_limiting($time_slot, $count, $user_marked='') {
    $user_marked = empty($user_marked) ? get_client_ip() : $user_marked;
    $cache_key = 'rate.limiting:'.$user_marked;
    $redis = new \Redis;
    $options = array (
        'host'          => C('REDIS_HOST') ? C('REDIS_HOST') : '127.0.0.1',
        'port'          => C('REDIS_PORT') ? C('REDIS_PORT') : 6379,
        'timeout'       => C('DATA_CACHE_TIMEOUT') ? C('DATA_CACHE_TIMEOUT') : false,
    );
    $res = $redis->connect($options['host'], $options['port'], $options['timeout']);
    $ret = array('status'=>0, 'info'=>'');
    if( false===$res) {
        $ret['info'] = '链接Redis失败';
        return $ret;
    }
    $redis->expire($cache_key, $time_slot); // 设置过期时间
    $list_len = $redis->llen($cache_key);
    if( $list_len<$count ) {
        $redis->lpush($cache_key, NOW_TIME);
        $ret['status'] = 1;
    } else {
        $datetime = $redis->lindex($cache_key, -1); // -1 标示列表最后一个元素
        if( (NOW_TIME-$datetime)<$time_slot ) {
            $ret['info'] = '访问频率超过了限制,请稍后重试。';
            // $redis->ltrim($cache_key, -1, 0); //清空列表
        } else {
            $redis->lpush($cache_key, NOW_TIME);
            // 
            $redis->ltrim($cache_key, 0, $count-1);
            $ret['status'] = 1;
        }
    }
    1==$ret['status'] && $ret['info'] = $list_len+1;
    return $ret;

}