php+mysql 封禁管理,防刷羊毛踩的坑

因公司需要,最近上了一个邀请好友,获得奖金的功能。上了一段时间,为了吸引客户,刷羊毛现象严重.要重新从数据里边封禁账号.二次处理数据的坑;
语言:php 框架tp5

实际需求 ①:ipv4 去前三位ip一致,保留三个账号,其余封掉
②:手机号前六位一致,保留十个账号,其余封掉
③:手机号前七位一致,保留三个账号,其余封掉
④:手机号前八位一致,保留一个账号,其余封掉
⑤:以上规则,都是封禁每个代理下的

刚开始的解决思路是

查询出所有的不同的IP,手机号,查出所有的代理,再foreach查询去处理

	 //查询不同代理
        $source=Db::name('user')->field('source')->distinct(true)->select();
        //查询不同ip
        $ip=Db::name('user')->field('ip')->distinct(true)->select();
        //循环ip
        foreach($ip as $k=>$v){
            //循环代理
            foreach($source as $k2=>$v2){
                //分解ip
                $arrIp = explode('.',$v['ip']);
                $ip=$arrIp[0].'.'.$arrIp['1'].'.'.$arrIp['2'];
                //查询条件
                $map['source']=$v2['source'];
                $map['ip']=['like','%'.$ip];
                //查出总数
                $count=Db::name('user')->field('id')->where($map)->count();
                if($count>3){
                    //变为应封禁状态
                    Db::name('user')->where($map)->update(['statusBan'=>'2']);
                }
            }
        }

可能很多朋友都跟我一个想法,而且这是一个定时脚本,暂时忽略了注册时间问题
这个效率可想而知,基本都会502

新的解决方案是查库,在mysql处理好这一切

首先,查出前三位ip

//先查出 ip前三段
	SELECT
	substring_index(registerIP, '.', 3)
	FROM
	ban;
	//解释一下sql 
	EXPLAIN SELECT
	substring_index(registerIP, '.', 3)
	FROM
	ban;
	//type 只达到了index 使用了索引  2万条大概需要4s
	SELECT
	registerIP
	FROM
	ban;
	//type 只达到了index 使用了索引  2万条大概需要1.6s
	//这个mysql函数速度还是可以用的 substring_index 这里不过多解释 不知道的可以搜一下
//根据ip 分组 得到ip出现的次数
	SELECT
	substring_index(registerIP, '.', 3) AS ip,
	count(registerIP) AS count
	FROM
	ban
	GROUP BY
	substring_index(registerIP, '.', 3);
	//也是两秒左右
//我们最终是要每个代理下的ip
	SELECT
	source,//上级
	substring_index(registerIP, '.', 3) AS ip,//切割ip
	COUNT(registerIP) AS count//得到数量
	FROM
	user
	GROUP BY
	substring_index(registerIP, '.', 3),//根据切割的ip分组
	source
	HAVING
	count > 3 //出现次数大于三次
	ORDER BY
	count DESC
	//1.17s结束查询 每个代理下面的ip 和出现的次数都得到了 省去了两步for循环

php代码:

	//查出分组
	$arrIp = Db::query("SELECT source,substring_index(registerIP, '.', 3) AS ip, COUNT(registerIP) AS count  FROM user WHERE `status` <> '3' and `status` <> '1' and addtime >=:time AND registerIP > 0 GROUP BY substring_index(registerIP, '.', 3), source HAVING count > 3 ORDER BY count DESC", ['time' => $time]);
	//习惯过滤一遍
        foreach ($iparr as $k => $v) {
            if ($v['count'] < 3) {
                unset($iparr[$k]);
            }
        }
   //后边省略 .....

手机号如果这样处理的话,也会崩溃
错误的php代码就不展示了

//不过多的分析了
 SELECT source,//上级
 substring(mobile,1,6) AS mobile,//切割手机号 6或者7 8 
 COUNT(mobile) AS count //得到总数
	FROM
	user
 GROUP BY //分组
	substring(mobile,1,6),
	source
 HAVING
	count > 10 //条件
 ORDER BY
	count DESC
//substring() mysql 内置函数
//两万数据 效率 0.0xx 级

运用 substring,substring_index
这样成功解决了Ip和手机号处理的问题;实际应用中,加上判断注册时间,处理状态,效率更加;php如果处理过多的地sql查询 ,还是mysql处理好

新手上路,多多关照

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值