当前位置: 移动技术网 > IT编程>开发语言>PHP > [PHP] 频率限制类

[PHP] 频率限制类

2019年03月28日  | 移动技术网IT编程  | 我要评论

贵州省人事考试信息,幻梦游仙,重生轮回眼传说txt

比如要实现

单个ip限制60秒1次
单个关键字,比如手机号,限制60秒1次,3600秒10次

 

<?php
class sina_mail_webantispam {

    const prefix_whitelist = 'w:';
    const prefix_kill = 'k:';
    const prefix_verifycode = 'c:';
    const prefix_verified = 'v:';
    const status_update = '[u]';

    private $mc = null;
    private $config = null;
    private $whitelist = array();
    private $keyprefix = '';
    private $intervals = array();
    private $updates = array();
    private $status = array();

    public function __construct($mc, $config) {
        $this->mc = $mc;
        $this->config = $config;
        if (isset($this->config->prefix)) {
            $this->keyprefix = $this->config->prefix;
        }
        if (isset($this->config->whitelistkey)) {
            $wls = $this->mc->get($this->config->whitelistkey);
            if (!empty($wls)) {
                $this->whitelist = & $wls;
            }
        }
    }

    public function setwhitelist(&$whitelist) {
        $this->whitelist = & $whitelist;
    }
    /*验证限制规则*/
    public function check($ip = null, $key = null) {
        if (!$ip && !$key) {
            return false;
        }

        if ($key) {
            if (!is_array($key)) {
                $keys = array($key);
            } else {
                $keys = $key;
            }
        }

        // first filter by whitelist
        if (!empty($this->whitelist)) {
            if ($ip && $this->filterbywhitelist($ip, 'ip')) {
                $this->status[self::prefix_whitelist . $ip] = 1;
                return true;
            }
            if ($keys) {
                foreach ($keys as $key) {
                    if ($this->filterbywhitelist($key, 'key')) {
                        $this->status[self::prefix_whitelist . $key] = 1;
                        return true;
                    }
                }
            }
        }

        if ($ip) {
            $ip = $this->keyprefix . $ip;
        }

        // second, check verified ok
        if (!empty($this->config->verified)) {
            if ($ip && $this->mc->get(self::prefix_verified . $ip)) {
                $this->status[self::prefix_verified . $ip] = 1;
                return true;
            }
            if ($keys) {
                foreach ($keys as $key) {
                    $verifiedkey = self::prefix_verified . $this->keyprefix . $key;
                    if ($this->mc->get($verifiedkey)) {
                        $this->status[$verifiedkey] = 1;
                        return true;
                    }
                }
            }
        }

        $kos = !empty($this->config->kill);
        // check killed
        if ($kos) {
            if ($ip && $this->mc->get(self::prefix_kill . $ip)) {
                $this->status[self::prefix_kill . $ip] = 1;
                return false;
            }
            if ($keys) {
                foreach ($keys as $key) {
                    $killkey = self::prefix_kill . $this->keyprefix . $key;
                    if ($this->mc->get($killkey)) {
                        $this->status[$killkey] = 1;
                        return false;
                    }
                }
            }
        }

        // check ip rule
        if ($ip && isset($this->config->ip)) {
            if (!$this->checkrule($ip, $this->config->ip)) {
                if ($kos && $this->mc->set(self::prefix_kill . $ip, 1, intval($this->config->kill))) {
                    $this->status[self::prefix_kill . $ip] = 1;
                }
                return false;
            }
        }

        // check keys rule
        if ($keys && isset($this->config->key)) {
            foreach ($keys as $key) {
                if (!$this->checkrule($this->keyprefix . $key, $this->config->key)) {
                    $killkey = self::prefix_kill . $this->keyprefix . $key;
                    if ($kos && $this->mc->set($killkey, 1, intval($this->config->kill))) {
                        $this->status[$killkey] = 1;
                    }
                    return false;
                }
            }
        }

        return true;
    }
    /*更新限制规则*/
    public function update($c = 1, $ip = null, $key = null) {
        if (is_null($ip) && is_null($key)) {
            if (!empty($this->updates)) {
                foreach ($this->updates as $k => $v) {
                    if (!$v && isset($this->intervals[$k])) {
                        if ($this->mc->add($k, $c, false,$this->intervals[$k])) {
                            $this->status[self::status_update . $k] = $c;
                            continue;
                        }
                    }
                    $r = $this->mc->increment($k, $c);
                    $this->status[self::status_update . $k] = $r;
                }
            }
        } else {
            if (!is_null($ip) && isset($this->config->ip)) {
                $rule = $this->config->ip;
                foreach ($rule as $interval => $limit) {
                    $k = $this->keyprefix . $ip . '_' . $interval;
                    if ($this->mc->add($k, $c,false,$interval)) {
                        $this->status[self::status_update . $k] = true;
                        continue;
                    }
                    $r = $this->mc->increment($k, $c);
                    $this->status[self::status_update . $k] = $r;
                }
            }
            if (!is_null($key) && isset($this->config->key)) {
                $rule = $this->config->key;
                if (!is_array($key)) {
                    $keys = array($key);
                } else {
                    $keys = $key;
                }
                foreach ($keys as $key) {
                    foreach ($rule as $interval => $limit) {
                        $k = $this->keyprefix . $key . '_' . $interval;
                        if ($this->mc->add($k, $c,false,$interval)) {
                            $this->status[self::status_update . $k] = true;
                            continue;
                        }
                        $r = $this->mc->increment($k, $c);
                        $this->status[self::status_update . $k] = $r;
                    }
                }
            }
        }
    }

    public function checkverifycode($key, $code) {
        $servcode = $this->mc->get(self::prefix_verifycode . $this->keyprefix . $key);
        if (strcasecmp($servcode, $code) == 0) {
            $verified = intval($this->config->verified);
            if ($verified > 0) {
                $r = $this->mc->set(self::prefix_verified . $this->keyprefix . $key, 1, false, $verified);
            } else {
                $r = true;
            }
            if ($r) {
                $this->mc->delete(self::prefix_verifycode . $this->keyprefix . $key);
            }
            return $r;
        }
        return false;
    }

    public function isverified($key) {
        $r = $this->mc->get(self::prefix_verified . $this->keyprefix . $key);
        if (!empty($r)) {
            return true;
        } else {
            return false;
        }
    }

    public function setverifycode($key, $code) {
        $verifytime = intval($this->config->verifytime);
        if ($verifytime < 1) {
            return false;
        }
        return $this->mc->set(self::prefix_verifycode . $this->keyprefix . $key, $code, false, $verifytime);
    }

    public function getstatus() {
        return $this->status;
    }

    private function filterbywhitelist($value, $key) {
//        if (empty($this->whitelist[$key])) {
//            return false;
//        }
//        $ls = & $this->whitelist[$key];
        $ls = & $this->whitelist;
        foreach ($ls as $i) {
            if ($i[strlen($i) - 1] == '.') { // ip segment
                if (strpos($value, $i) === 0) {
                    return true;
                }
            } else {
                if (strcmp($i, $value) === 0) {
                    return true;
                }
            }
        }
        return false;
    }

    private function checkrule($key, $rule) {
        $flag = true;
        if (!empty($rule)) {
            foreach ($rule as $interval => $limit) {
                $k = $key . '_' . $interval;
                $c = $this->mc->get($k);
                if (!$c) {
                    $this->updates[$k] = 0;
                    $this->intervals[$k] = $interval;
                    $this->status[$k] = 0;
                } else {
                    $this->updates[$k] = $c;
                    $this->status[$k] = $c;
                    if ($c >= $limit) {
                        $flag = false;
                    }
                }
            }
        }
        return $flag;
    }

    public static function getinstance($conf) {
        $mc = new memcache();
        $mc->connect("115.159.28.112");
        $conf=json_decode(json_encode($conf));
        return new self($mc, $conf);
    }

}
/*
单个ip限制60秒1次
单个关键字,比如手机号,限制60秒1次,3600秒10次
*/
$conf=array(
            'prefix' => 'selfservice:',
            'key' => array(60 => 1,3600=>10),
            'ip' => array(60 => 1),
        );
$spam=sina_mail_webantispam::getinstance($conf);
if(!$spam->check('127.25.12.123',17610725730)){
	echo "limit...";
	exit;
}

//更新频率限制
$spam->update();

  

 memache中最终的存储key

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网